diff options
Diffstat (limited to 'crates/ra_ide/src/runnables.rs')
-rw-r--r-- | crates/ra_ide/src/runnables.rs | 50 |
1 files changed, 16 insertions, 34 deletions
diff --git a/crates/ra_ide/src/runnables.rs b/crates/ra_ide/src/runnables.rs index be2a67d0a..74877e90f 100644 --- a/crates/ra_ide/src/runnables.rs +++ b/crates/ra_ide/src/runnables.rs | |||
@@ -1,8 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{InFile, SourceBinder}; | 3 | use hir::Semantics; |
4 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | use ra_db::SourceDatabase; | ||
6 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::RootDatabase; |
7 | use ra_syntax::{ | 6 | use ra_syntax::{ |
8 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, | 7 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, |
@@ -42,46 +41,33 @@ pub enum RunnableKind { | |||
42 | } | 41 | } |
43 | 42 | ||
44 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 43 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
45 | let parse = db.parse(file_id); | 44 | let sema = Semantics::new(db); |
46 | let mut sb = SourceBinder::new(db); | 45 | let source_file = sema.parse(file_id); |
47 | parse.tree().syntax().descendants().filter_map(|i| runnable(db, &mut sb, file_id, i)).collect() | 46 | source_file.syntax().descendants().filter_map(|i| runnable(&sema, i)).collect() |
48 | } | 47 | } |
49 | 48 | ||
50 | fn runnable( | 49 | fn runnable(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { |
51 | db: &RootDatabase, | ||
52 | source_binder: &mut SourceBinder<RootDatabase>, | ||
53 | file_id: FileId, | ||
54 | item: SyntaxNode, | ||
55 | ) -> Option<Runnable> { | ||
56 | match_ast! { | 50 | match_ast! { |
57 | match item { | 51 | match item { |
58 | ast::FnDef(it) => { runnable_fn(db, source_binder, file_id, it) }, | 52 | ast::FnDef(it) => { runnable_fn(sema, it) }, |
59 | ast::Module(it) => { runnable_mod(db, source_binder, file_id, it) }, | 53 | ast::Module(it) => { runnable_mod(sema, it) }, |
60 | _ => { None }, | 54 | _ => None, |
61 | } | 55 | } |
62 | } | 56 | } |
63 | } | 57 | } |
64 | 58 | ||
65 | fn runnable_fn( | 59 | fn runnable_fn(sema: &Semantics<RootDatabase>, fn_def: ast::FnDef) -> Option<Runnable> { |
66 | db: &RootDatabase, | ||
67 | source_binder: &mut SourceBinder<RootDatabase>, | ||
68 | file_id: FileId, | ||
69 | fn_def: ast::FnDef, | ||
70 | ) -> Option<Runnable> { | ||
71 | let name_string = fn_def.name()?.text().to_string(); | 60 | let name_string = fn_def.name()?.text().to_string(); |
72 | 61 | ||
73 | let kind = if name_string == "main" { | 62 | let kind = if name_string == "main" { |
74 | RunnableKind::Bin | 63 | RunnableKind::Bin |
75 | } else { | 64 | } else { |
76 | let test_id = if let Some(module) = source_binder | 65 | let test_id = if let Some(module) = sema.to_def(&fn_def).map(|def| def.module(sema.db)) { |
77 | .to_def(InFile::new(file_id.into(), fn_def.clone())) | ||
78 | .map(|def| def.module(db)) | ||
79 | { | ||
80 | let path = module | 66 | let path = module |
81 | .path_to_root(db) | 67 | .path_to_root(sema.db) |
82 | .into_iter() | 68 | .into_iter() |
83 | .rev() | 69 | .rev() |
84 | .filter_map(|it| it.name(db)) | 70 | .filter_map(|it| it.name(sema.db)) |
85 | .map(|name| name.to_string()) | 71 | .map(|name| name.to_string()) |
86 | .chain(std::iter::once(name_string)) | 72 | .chain(std::iter::once(name_string)) |
87 | .join("::"); | 73 | .join("::"); |
@@ -115,12 +101,7 @@ fn has_test_related_attribute(fn_def: &ast::FnDef) -> bool { | |||
115 | .any(|attribute_text| attribute_text.contains("test")) | 101 | .any(|attribute_text| attribute_text.contains("test")) |
116 | } | 102 | } |
117 | 103 | ||
118 | fn runnable_mod( | 104 | fn runnable_mod(sema: &Semantics<RootDatabase>, module: ast::Module) -> Option<Runnable> { |
119 | db: &RootDatabase, | ||
120 | source_binder: &mut SourceBinder<RootDatabase>, | ||
121 | file_id: FileId, | ||
122 | module: ast::Module, | ||
123 | ) -> Option<Runnable> { | ||
124 | let has_test_function = module | 105 | let has_test_function = module |
125 | .item_list()? | 106 | .item_list()? |
126 | .items() | 107 | .items() |
@@ -133,9 +114,10 @@ fn runnable_mod( | |||
133 | return None; | 114 | return None; |
134 | } | 115 | } |
135 | let range = module.syntax().text_range(); | 116 | let range = module.syntax().text_range(); |
136 | let module = source_binder.to_def(InFile::new(file_id.into(), module))?; | 117 | let module = sema.to_def(&module)?; |
137 | 118 | ||
138 | let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::"); | 119 | let path = |
120 | module.path_to_root(sema.db).into_iter().rev().filter_map(|it| it.name(sema.db)).join("::"); | ||
139 | Some(Runnable { range, kind: RunnableKind::TestMod { path } }) | 121 | Some(Runnable { range, kind: RunnableKind::TestMod { path } }) |
140 | } | 122 | } |
141 | 123 | ||