aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/descriptors/module
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/descriptors/module')
-rw-r--r--crates/ra_analysis/src/descriptors/module/imp.rs16
-rw-r--r--crates/ra_analysis/src/descriptors/module/mod.rs43
-rw-r--r--crates/ra_analysis/src/descriptors/module/scope.rs6
3 files changed, 37 insertions, 28 deletions
diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs
index b5c232ea4..ade96ddc0 100644
--- a/crates/ra_analysis/src/descriptors/module/imp.rs
+++ b/crates/ra_analysis/src/descriptors/module/imp.rs
@@ -41,8 +41,8 @@ pub(crate) fn submodules(
41 db::check_canceled(db)?; 41 db::check_canceled(db)?;
42 let file_id = source.file_id(); 42 let file_id = source.file_id();
43 let submodules = match source.resolve(db) { 43 let submodules = match source.resolve(db) {
44 ModuleSourceNode::Root(it) => collect_submodules(file_id, it.borrowed()), 44 ModuleSourceNode::SourceFile(it) => collect_submodules(file_id, it.borrowed()),
45 ModuleSourceNode::Inline(it) => it 45 ModuleSourceNode::Module(it) => it
46 .borrowed() 46 .borrowed()
47 .item_list() 47 .item_list()
48 .map(|it| collect_submodules(file_id, it)) 48 .map(|it| collect_submodules(file_id, it))
@@ -89,8 +89,8 @@ pub(crate) fn module_scope(
89 let tree = db.module_tree(source_root_id)?; 89 let tree = db.module_tree(source_root_id)?;
90 let source = module_id.source(&tree).resolve(db); 90 let source = module_id.source(&tree).resolve(db);
91 let res = match source { 91 let res = match source {
92 ModuleSourceNode::Root(root) => ModuleScope::new(root.borrowed().items()), 92 ModuleSourceNode::SourceFile(it) => ModuleScope::new(it.borrowed().items()),
93 ModuleSourceNode::Inline(inline) => match inline.borrowed().item_list() { 93 ModuleSourceNode::Module(it) => match it.borrowed().item_list() {
94 Some(items) => ModuleScope::new(items.items()), 94 Some(items) => ModuleScope::new(items.items()),
95 None => ModuleScope::new(std::iter::empty()), 95 None => ModuleScope::new(std::iter::empty()),
96 }, 96 },
@@ -121,7 +121,7 @@ fn create_module_tree<'a>(
121 121
122 let source_root = db.source_root(source_root); 122 let source_root = db.source_root(source_root);
123 for &file_id in source_root.files.iter() { 123 for &file_id in source_root.files.iter() {
124 let source = ModuleSource::File(file_id); 124 let source = ModuleSource::SourceFile(file_id);
125 if visited.contains(&source) { 125 if visited.contains(&source) {
126 continue; // TODO: use explicit crate_roots here 126 continue; // TODO: use explicit crate_roots here
127 } 127 }
@@ -181,7 +181,7 @@ fn build_subtree(
181 visited, 181 visited,
182 roots, 182 roots,
183 Some(link), 183 Some(link),
184 ModuleSource::File(file_id), 184 ModuleSource::SourceFile(file_id),
185 ), 185 ),
186 }) 186 })
187 .collect::<Cancelable<Vec<_>>>()?; 187 .collect::<Cancelable<Vec<_>>>()?;
@@ -213,8 +213,8 @@ fn resolve_submodule(
213 file_resolver: &FileResolverImp, 213 file_resolver: &FileResolverImp,
214) -> (Vec<FileId>, Option<Problem>) { 214) -> (Vec<FileId>, Option<Problem>) {
215 let file_id = match source { 215 let file_id = match source {
216 ModuleSource::File(it) => it, 216 ModuleSource::SourceFile(it) => it,
217 ModuleSource::Inline(..) => { 217 ModuleSource::Module(..) => {
218 // TODO 218 // TODO
219 return (Vec::new(), None); 219 return (Vec::new(), None);
220 } 220 }
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs
index 03330240d..bc1148b22 100644
--- a/crates/ra_analysis/src/descriptors/module/mod.rs
+++ b/crates/ra_analysis/src/descriptors/module/mod.rs
@@ -3,7 +3,7 @@ pub(crate) mod scope;
3 3
4use ra_syntax::{ 4use ra_syntax::{
5 ast::{self, AstNode, NameOwner}, 5 ast::{self, AstNode, NameOwner},
6 SmolStr, SyntaxNode, 6 SmolStr, SyntaxNode, SyntaxNodeRef,
7}; 7};
8use relative_path::RelativePathBuf; 8use relative_path::RelativePathBuf;
9 9
@@ -41,19 +41,18 @@ impl ModuleTree {
41 41
42/// `ModuleSource` is the syntax tree element that produced this module: 42/// `ModuleSource` is the syntax tree element that produced this module:
43/// either a file, or an inlinde module. 43/// either a file, or an inlinde module.
44/// TODO: we don't produce Inline modules yet
45#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 44#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
46pub(crate) enum ModuleSource { 45pub(crate) enum ModuleSource {
47 File(FileId), 46 SourceFile(FileId),
48 #[allow(dead_code)] 47 #[allow(dead_code)]
49 Inline(SyntaxPtr), 48 Module(SyntaxPtr),
50} 49}
51 50
52/// An owned syntax node for a module. Unlike `ModuleSource`, 51/// An owned syntax node for a module. Unlike `ModuleSource`,
53/// this holds onto the AST for the whole file. 52/// this holds onto the AST for the whole file.
54enum ModuleSourceNode { 53enum ModuleSourceNode {
55 Root(ast::RootNode), 54 SourceFile(ast::SourceFileNode),
56 Inline(ast::ModuleNode), 55 Module(ast::ModuleNode),
57} 56}
58 57
59#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 58#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
@@ -135,14 +134,14 @@ impl LinkId {
135 ) -> ast::ModuleNode { 134 ) -> ast::ModuleNode {
136 let owner = self.owner(tree); 135 let owner = self.owner(tree);
137 match owner.source(tree).resolve(db) { 136 match owner.source(tree).resolve(db) {
138 ModuleSourceNode::Root(root) => { 137 ModuleSourceNode::SourceFile(root) => {
139 let ast = imp::modules(root.borrowed()) 138 let ast = imp::modules(root.borrowed())
140 .find(|(name, _)| name == &tree.link(self).name) 139 .find(|(name, _)| name == &tree.link(self).name)
141 .unwrap() 140 .unwrap()
142 .1; 141 .1;
143 ast.owned() 142 ast.owned()
144 } 143 }
145 ModuleSourceNode::Inline(it) => it, 144 ModuleSourceNode::Module(it) => it,
146 } 145 }
147 } 146 }
148} 147}
@@ -155,37 +154,47 @@ struct ModuleData {
155} 154}
156 155
157impl ModuleSource { 156impl ModuleSource {
157 pub(crate) fn for_node(file_id: FileId, node: SyntaxNodeRef) -> ModuleSource {
158 for node in node.ancestors() {
159 if let Some(m) = ast::Module::cast(node) {
160 if !m.has_semi() {
161 return ModuleSource::new_inline(file_id, m);
162 }
163 }
164 }
165 ModuleSource::SourceFile(file_id)
166 }
158 pub(crate) fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource { 167 pub(crate) fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource {
159 assert!(!module.has_semi()); 168 assert!(!module.has_semi());
160 let ptr = SyntaxPtr::new(file_id, module.syntax()); 169 let ptr = SyntaxPtr::new(file_id, module.syntax());
161 ModuleSource::Inline(ptr) 170 ModuleSource::Module(ptr)
162 } 171 }
163 172
164 pub(crate) fn as_file(self) -> Option<FileId> { 173 pub(crate) fn as_file(self) -> Option<FileId> {
165 match self { 174 match self {
166 ModuleSource::File(f) => Some(f), 175 ModuleSource::SourceFile(f) => Some(f),
167 ModuleSource::Inline(..) => None, 176 ModuleSource::Module(..) => None,
168 } 177 }
169 } 178 }
170 179
171 pub(crate) fn file_id(self) -> FileId { 180 pub(crate) fn file_id(self) -> FileId {
172 match self { 181 match self {
173 ModuleSource::File(f) => f, 182 ModuleSource::SourceFile(f) => f,
174 ModuleSource::Inline(ptr) => ptr.file_id(), 183 ModuleSource::Module(ptr) => ptr.file_id(),
175 } 184 }
176 } 185 }
177 186
178 fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode { 187 fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode {
179 match self { 188 match self {
180 ModuleSource::File(file_id) => { 189 ModuleSource::SourceFile(file_id) => {
181 let syntax = db.file_syntax(file_id); 190 let syntax = db.file_syntax(file_id);
182 ModuleSourceNode::Root(syntax.ast().owned()) 191 ModuleSourceNode::SourceFile(syntax.ast().owned())
183 } 192 }
184 ModuleSource::Inline(ptr) => { 193 ModuleSource::Module(ptr) => {
185 let syntax = db.resolve_syntax_ptr(ptr); 194 let syntax = db.resolve_syntax_ptr(ptr);
186 let syntax = syntax.borrowed(); 195 let syntax = syntax.borrowed();
187 let module = ast::Module::cast(syntax).unwrap(); 196 let module = ast::Module::cast(syntax).unwrap();
188 ModuleSourceNode::Inline(module.owned()) 197 ModuleSourceNode::Module(module.owned())
189 } 198 }
190 } 199 }
191 } 200 }
diff --git a/crates/ra_analysis/src/descriptors/module/scope.rs b/crates/ra_analysis/src/descriptors/module/scope.rs
index 215b31f8e..4490228e4 100644
--- a/crates/ra_analysis/src/descriptors/module/scope.rs
+++ b/crates/ra_analysis/src/descriptors/module/scope.rs
@@ -25,7 +25,7 @@ enum EntryKind {
25} 25}
26 26
27impl ModuleScope { 27impl ModuleScope {
28 pub(crate) fn new<'a>(items: impl Iterator<Item = ast::ModuleItem<'a>>) -> ModuleScope { 28 pub(super) fn new<'a>(items: impl Iterator<Item = ast::ModuleItem<'a>>) -> ModuleScope {
29 let mut entries = Vec::new(); 29 let mut entries = Vec::new();
30 for item in items { 30 for item in items {
31 let entry = match item { 31 let entry = match item {
@@ -95,10 +95,10 @@ fn collect_imports(tree: ast::UseTree, acc: &mut Vec<Entry>) {
95#[cfg(test)] 95#[cfg(test)]
96mod tests { 96mod tests {
97 use super::*; 97 use super::*;
98 use ra_syntax::{ast::ModuleItemOwner, File}; 98 use ra_syntax::{ast::ModuleItemOwner, SourceFileNode};
99 99
100 fn do_check(code: &str, expected: &[&str]) { 100 fn do_check(code: &str, expected: &[&str]) {
101 let file = File::parse(&code); 101 let file = SourceFileNode::parse(&code);
102 let scope = ModuleScope::new(file.ast().items()); 102 let scope = ModuleScope::new(file.ast().items());
103 let actual = scope.entries.iter().map(|it| it.name()).collect::<Vec<_>>(); 103 let actual = scope.entries.iter().map(|it| it.name()).collect::<Vec<_>>();
104 assert_eq!(expected, actual.as_slice()); 104 assert_eq!(expected, actual.as_slice());