diff options
Diffstat (limited to 'crates/ra_editor/src/scope/mod_scope.rs')
-rw-r--r-- | crates/ra_editor/src/scope/mod_scope.rs | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/crates/ra_editor/src/scope/mod_scope.rs b/crates/ra_editor/src/scope/mod_scope.rs index d2a3e7c58..8d7e408f8 100644 --- a/crates/ra_editor/src/scope/mod_scope.rs +++ b/crates/ra_editor/src/scope/mod_scope.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use ra_syntax::{ | 1 | use ra_syntax::{ |
2 | AstNode, SyntaxNode, SyntaxNodeRef, SmolStr, | ||
3 | ast::{self, AstChildren}, | 2 | ast::{self, AstChildren}, |
3 | AstNode, SmolStr, SyntaxNode, SyntaxNodeRef, | ||
4 | }; | 4 | }; |
5 | 5 | ||
6 | pub struct ModuleScope { | 6 | pub struct ModuleScope { |
@@ -13,7 +13,8 @@ pub struct Entry { | |||
13 | } | 13 | } |
14 | 14 | ||
15 | enum EntryKind { | 15 | enum EntryKind { |
16 | Item, Import, | 16 | Item, |
17 | Import, | ||
17 | } | 18 | } |
18 | 19 | ||
19 | impl ModuleScope { | 20 | impl ModuleScope { |
@@ -34,9 +35,8 @@ impl ModuleScope { | |||
34 | collect_imports(tree, &mut entries); | 35 | collect_imports(tree, &mut entries); |
35 | } | 36 | } |
36 | continue; | 37 | continue; |
37 | }, | 38 | } |
38 | ast::ModuleItem::ExternCrateItem(_) | | 39 | ast::ModuleItem::ExternCrateItem(_) | ast::ModuleItem::ImplItem(_) => continue, |
39 | ast::ModuleItem::ImplItem(_) => continue, | ||
40 | }; | 40 | }; |
41 | entries.extend(entry) | 41 | entries.extend(entry) |
42 | } | 42 | } |
@@ -52,20 +52,22 @@ impl ModuleScope { | |||
52 | impl Entry { | 52 | impl Entry { |
53 | fn new<'a>(item: impl ast::NameOwner<'a>) -> Option<Entry> { | 53 | fn new<'a>(item: impl ast::NameOwner<'a>) -> Option<Entry> { |
54 | let name = item.name()?; | 54 | let name = item.name()?; |
55 | Some(Entry { node: name.syntax().owned(), kind: EntryKind::Item }) | 55 | Some(Entry { |
56 | node: name.syntax().owned(), | ||
57 | kind: EntryKind::Item, | ||
58 | }) | ||
56 | } | 59 | } |
57 | fn new_import(path: ast::Path) -> Option<Entry> { | 60 | fn new_import(path: ast::Path) -> Option<Entry> { |
58 | let name_ref = path.segment()?.name_ref()?; | 61 | let name_ref = path.segment()?.name_ref()?; |
59 | Some(Entry { node: name_ref.syntax().owned(), kind: EntryKind::Import }) | 62 | Some(Entry { |
63 | node: name_ref.syntax().owned(), | ||
64 | kind: EntryKind::Import, | ||
65 | }) | ||
60 | } | 66 | } |
61 | pub fn name(&self) -> SmolStr { | 67 | pub fn name(&self) -> SmolStr { |
62 | match self.kind { | 68 | match self.kind { |
63 | EntryKind::Item => | 69 | EntryKind::Item => ast::Name::cast(self.node.borrowed()).unwrap().text(), |
64 | ast::Name::cast(self.node.borrowed()).unwrap() | 70 | EntryKind::Import => ast::NameRef::cast(self.node.borrowed()).unwrap().text(), |
65 | .text(), | ||
66 | EntryKind::Import => | ||
67 | ast::NameRef::cast(self.node.borrowed()).unwrap() | ||
68 | .text(), | ||
69 | } | 71 | } |
70 | } | 72 | } |
71 | pub fn syntax(&self) -> SyntaxNodeRef { | 73 | pub fn syntax(&self) -> SyntaxNodeRef { |
@@ -75,32 +77,31 @@ impl Entry { | |||
75 | 77 | ||
76 | fn collect_imports(tree: ast::UseTree, acc: &mut Vec<Entry>) { | 78 | fn collect_imports(tree: ast::UseTree, acc: &mut Vec<Entry>) { |
77 | if let Some(use_tree_list) = tree.use_tree_list() { | 79 | if let Some(use_tree_list) = tree.use_tree_list() { |
78 | return use_tree_list.use_trees().for_each(|it| collect_imports(it, acc)); | 80 | return use_tree_list |
81 | .use_trees() | ||
82 | .for_each(|it| collect_imports(it, acc)); | ||
79 | } | 83 | } |
80 | if let Some(path) = tree.path() { | 84 | if let Some(path) = tree.path() { |
81 | acc.extend(Entry::new_import(path)); | 85 | acc.extend(Entry::new_import(path)); |
82 | } | 86 | } |
83 | } | 87 | } |
84 | 88 | ||
85 | |||
86 | #[cfg(test)] | 89 | #[cfg(test)] |
87 | mod tests { | 90 | mod tests { |
88 | use super::*; | 91 | use super::*; |
89 | use ra_syntax::{File, ast::ModuleItemOwner}; | 92 | use ra_syntax::{ast::ModuleItemOwner, File}; |
90 | 93 | ||
91 | fn do_check(code: &str, expected: &[&str]) { | 94 | fn do_check(code: &str, expected: &[&str]) { |
92 | let file = File::parse(&code); | 95 | let file = File::parse(&code); |
93 | let scope = ModuleScope::new(file.ast().items()); | 96 | let scope = ModuleScope::new(file.ast().items()); |
94 | let actual = scope.entries | 97 | let actual = scope.entries.iter().map(|it| it.name()).collect::<Vec<_>>(); |
95 | .iter() | ||
96 | .map(|it| it.name()) | ||
97 | .collect::<Vec<_>>(); | ||
98 | assert_eq!(expected, actual.as_slice()); | 98 | assert_eq!(expected, actual.as_slice()); |
99 | } | 99 | } |
100 | 100 | ||
101 | #[test] | 101 | #[test] |
102 | fn test_module_scope() { | 102 | fn test_module_scope() { |
103 | do_check(" | 103 | do_check( |
104 | " | ||
104 | struct Foo; | 105 | struct Foo; |
105 | enum Bar {} | 106 | enum Bar {} |
106 | mod baz {} | 107 | mod baz {} |
@@ -110,6 +111,8 @@ mod tests { | |||
110 | t, | 111 | t, |
111 | }; | 112 | }; |
112 | type T = (); | 113 | type T = (); |
113 | ", &["Foo", "Bar", "baz", "quux", "z", "t", "T"]) | 114 | ", |
115 | &["Foo", "Bar", "baz", "quux", "z", "t", "T"], | ||
116 | ) | ||
114 | } | 117 | } |
115 | } | 118 | } |