aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/runnables.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/runnables.rs')
-rw-r--r--crates/ide/src/runnables.rs53
1 files changed, 26 insertions, 27 deletions
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index c893afc7c..557563d7e 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -2,11 +2,11 @@ use std::fmt;
2 2
3use assists::utils::test_related_attribute; 3use assists::utils::test_related_attribute;
4use cfg::CfgExpr; 4use cfg::CfgExpr;
5use hir::{AsAssocItem, HasAttrs, InFile, Semantics}; 5use hir::{AsAssocItem, HasAttrs, HasSource, Semantics};
6use ide_db::RootDatabase; 6use ide_db::RootDatabase;
7use itertools::Itertools; 7use itertools::Itertools;
8use syntax::{ 8use syntax::{
9 ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, 9 ast::{self, AstNode, AttrsOwner, ModuleItemOwner},
10 match_ast, SyntaxNode, 10 match_ast, SyntaxNode,
11}; 11};
12 12
@@ -96,17 +96,16 @@ impl Runnable {
96pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { 96pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
97 let sema = Semantics::new(db); 97 let sema = Semantics::new(db);
98 let source_file = sema.parse(file_id); 98 let source_file = sema.parse(file_id);
99 source_file.syntax().descendants().filter_map(|i| runnable(&sema, i, file_id)).collect() 99 source_file.syntax().descendants().filter_map(|i| runnable(&sema, i)).collect()
100} 100}
101 101
102pub(crate) fn runnable( 102pub(crate) fn runnable(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> {
103 sema: &Semantics<RootDatabase>,
104 item: SyntaxNode,
105 file_id: FileId,
106) -> Option<Runnable> {
107 let runnable_item = match_ast! { 103 let runnable_item = match_ast! {
108 match (item.clone()) { 104 match (item.clone()) {
109 ast::Fn(it) => runnable_fn(sema, it, file_id), 105 ast::Fn(func) => {
106 let def = sema.to_def(&func)?;
107 runnable_fn(sema, def)
108 },
110 ast::Module(it) => runnable_mod(sema, it), 109 ast::Module(it) => runnable_mod(sema, it),
111 _ => None, 110 _ => None,
112 } 111 }
@@ -114,23 +113,23 @@ pub(crate) fn runnable(
114 runnable_item.or_else(|| runnable_doctest(sema, item)) 113 runnable_item.or_else(|| runnable_doctest(sema, item))
115} 114}
116 115
117fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) -> Option<Runnable> { 116pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> {
118 let def = sema.to_def(&func)?; 117 let func = def.source(sema.db)?;
119 let name_string = func.name()?.text().to_string(); 118 let name_string = def.name(sema.db).to_string();
120 119
121 let kind = if name_string == "main" { 120 let kind = if name_string == "main" {
122 RunnableKind::Bin 121 RunnableKind::Bin
123 } else { 122 } else {
124 let canonical_path = sema.to_def(&func).and_then(|def| { 123 let canonical_path = {
125 let def: hir::ModuleDef = def.into(); 124 let def: hir::ModuleDef = def.into();
126 def.canonical_path(sema.db) 125 def.canonical_path(sema.db)
127 }); 126 };
128 let test_id = canonical_path.map(TestId::Path).unwrap_or(TestId::Name(name_string)); 127 let test_id = canonical_path.map(TestId::Path).unwrap_or(TestId::Name(name_string));
129 128
130 if test_related_attribute(&func).is_some() { 129 if test_related_attribute(&func.value).is_some() {
131 let attr = TestAttr::from_fn(&func); 130 let attr = TestAttr::from_fn(&func.value);
132 RunnableKind::Test { test_id, attr } 131 RunnableKind::Test { test_id, attr }
133 } else if func.has_atom_attr("bench") { 132 } else if func.value.has_atom_attr("bench") {
134 RunnableKind::Bench { test_id } 133 RunnableKind::Bench { test_id }
135 } else { 134 } else {
136 return None; 135 return None;
@@ -139,7 +138,7 @@ fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) -
139 138
140 let nav = NavigationTarget::from_named( 139 let nav = NavigationTarget::from_named(
141 sema.db, 140 sema.db,
142 InFile::new(file_id.into(), &func), 141 func.as_ref().map(|it| it as &dyn ast::NameOwner),
143 SymbolKind::Function, 142 SymbolKind::Function,
144 ); 143 );
145 let cfg = def.attrs(sema.db).cfg(); 144 let cfg = def.attrs(sema.db).cfg();
@@ -330,7 +329,7 @@ mod tests {
330 check( 329 check(
331 r#" 330 r#"
332//- /lib.rs 331//- /lib.rs
333<|> 332$0
334fn main() {} 333fn main() {}
335 334
336#[test] 335#[test]
@@ -426,7 +425,7 @@ fn bench() {}
426 check( 425 check(
427 r#" 426 r#"
428//- /lib.rs 427//- /lib.rs
429<|> 428$0
430fn main() {} 429fn main() {}
431 430
432/// ``` 431/// ```
@@ -574,7 +573,7 @@ struct StructWithRunnable(String);
574 check( 573 check(
575 r#" 574 r#"
576//- /lib.rs 575//- /lib.rs
577<|> 576$0
578fn main() {} 577fn main() {}
579 578
580struct Data; 579struct Data;
@@ -626,7 +625,7 @@ impl Data {
626 check( 625 check(
627 r#" 626 r#"
628//- /lib.rs 627//- /lib.rs
629<|> 628$0
630mod test_mod { 629mod test_mod {
631 #[test] 630 #[test]
632 fn test_foo1() {} 631 fn test_foo1() {}
@@ -680,7 +679,7 @@ mod test_mod {
680 check( 679 check(
681 r#" 680 r#"
682//- /lib.rs 681//- /lib.rs
683<|> 682$0
684mod root_tests { 683mod root_tests {
685 mod nested_tests_0 { 684 mod nested_tests_0 {
686 mod nested_tests_1 { 685 mod nested_tests_1 {
@@ -820,7 +819,7 @@ mod root_tests {
820 check( 819 check(
821 r#" 820 r#"
822//- /lib.rs crate:foo cfg:feature=foo 821//- /lib.rs crate:foo cfg:feature=foo
823<|> 822$0
824#[test] 823#[test]
825#[cfg(feature = "foo")] 824#[cfg(feature = "foo")]
826fn test_foo1() {} 825fn test_foo1() {}
@@ -865,7 +864,7 @@ fn test_foo1() {}
865 check( 864 check(
866 r#" 865 r#"
867//- /lib.rs crate:foo cfg:feature=foo,feature=bar 866//- /lib.rs crate:foo cfg:feature=foo,feature=bar
868<|> 867$0
869#[test] 868#[test]
870#[cfg(all(feature = "foo", feature = "bar"))] 869#[cfg(all(feature = "foo", feature = "bar"))]
871fn test_foo1() {} 870fn test_foo1() {}
@@ -920,7 +919,7 @@ fn test_foo1() {}
920 check( 919 check(
921 r#" 920 r#"
922//- /lib.rs 921//- /lib.rs
923<|> 922$0
924mod test_mod { 923mod test_mod {
925 fn foo1() {} 924 fn foo1() {}
926} 925}
@@ -939,7 +938,7 @@ mod test_mod {
939//- /lib.rs 938//- /lib.rs
940mod foo; 939mod foo;
941//- /foo.rs 940//- /foo.rs
942struct Foo;<|> 941struct Foo;$0
943impl Foo { 942impl Foo {
944 /// ``` 943 /// ```
945 /// let x = 5; 944 /// let x = 5;