aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/code_model_impl/module.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/code_model_impl/module.rs')
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs86
1 files changed, 37 insertions, 49 deletions
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index 67808d282..04301ae53 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -30,17 +30,14 @@ impl Module {
30 Module::new(def_id) 30 Module::new(def_id)
31 } 31 }
32 32
33 pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { 33 pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> {
34 let loc = self.def_id.loc(db); 34 let loc = self.def_id.loc(db);
35 let module_tree = db.module_tree(loc.source_root_id); 35 let module_tree = db.module_tree(loc.source_root_id);
36 let link = ctry!(loc.module_id.parent_link(&module_tree)); 36 let link = loc.module_id.parent_link(&module_tree)?;
37 Ok(Some(link.name(&module_tree).clone())) 37 Some(link.name(&module_tree).clone())
38 } 38 }
39 39
40 pub fn definition_source_impl( 40 pub fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) {
41 &self,
42 db: &impl HirDatabase,
43 ) -> Cancelable<(FileId, ModuleSource)> {
44 let loc = self.def_id.loc(db); 41 let loc = self.def_id.loc(db);
45 let file_id = loc.source_item_id.file_id.as_original_file(); 42 let file_id = loc.source_item_id.file_id.as_original_file();
46 let syntax_node = db.file_item(loc.source_item_id); 43 let syntax_node = db.file_item(loc.source_item_id);
@@ -50,40 +47,40 @@ impl Module {
50 let module = ast::Module::cast(&syntax_node).unwrap(); 47 let module = ast::Module::cast(&syntax_node).unwrap();
51 ModuleSource::Module(module.to_owned()) 48 ModuleSource::Module(module.to_owned())
52 }; 49 };
53 Ok((file_id, module_source)) 50 (file_id, module_source)
54 } 51 }
55 52
56 pub fn declaration_source_impl( 53 pub fn declaration_source_impl(
57 &self, 54 &self,
58 db: &impl HirDatabase, 55 db: &impl HirDatabase,
59 ) -> Cancelable<Option<(FileId, TreeArc<ast::Module>)>> { 56 ) -> Option<(FileId, TreeArc<ast::Module>)> {
60 let loc = self.def_id.loc(db); 57 let loc = self.def_id.loc(db);
61 let module_tree = db.module_tree(loc.source_root_id); 58 let module_tree = db.module_tree(loc.source_root_id);
62 let link = ctry!(loc.module_id.parent_link(&module_tree)); 59 let link = loc.module_id.parent_link(&module_tree)?;
63 let file_id = link 60 let file_id = link
64 .owner(&module_tree) 61 .owner(&module_tree)
65 .source(&module_tree) 62 .source(&module_tree)
66 .file_id 63 .file_id
67 .as_original_file(); 64 .as_original_file();
68 let src = link.source(&module_tree, db); 65 let src = link.source(&module_tree, db);
69 Ok(Some((file_id, src))) 66 Some((file_id, src))
70 } 67 }
71 68
72 pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { 69 pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> {
73 let root = self.crate_root(db)?; 70 let root = self.crate_root(db);
74 let loc = root.def_id.loc(db); 71 let loc = root.def_id.loc(db);
75 let file_id = loc.source_item_id.file_id.as_original_file(); 72 let file_id = loc.source_item_id.file_id.as_original_file();
76 73
77 let crate_graph = db.crate_graph(); 74 let crate_graph = db.crate_graph();
78 let crate_id = ctry!(crate_graph.crate_id_for_crate_root(file_id)); 75 let crate_id = crate_graph.crate_id_for_crate_root(file_id)?;
79 Ok(Some(Crate::new(crate_id))) 76 Some(Crate::new(crate_id))
80 } 77 }
81 78
82 pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Cancelable<Module> { 79 pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module {
83 let loc = self.def_id.loc(db); 80 let loc = self.def_id.loc(db);
84 let module_tree = db.module_tree(loc.source_root_id); 81 let module_tree = db.module_tree(loc.source_root_id);
85 let module_id = loc.module_id.crate_root(&module_tree); 82 let module_id = loc.module_id.crate_root(&module_tree);
86 Ok(Module::from_module_id(db, loc.source_root_id, module_id)) 83 Module::from_module_id(db, loc.source_root_id, module_id)
87 } 84 }
88 85
89 /// Finds a child module with the specified name. 86 /// Finds a child module with the specified name.
@@ -95,7 +92,7 @@ impl Module {
95 } 92 }
96 93
97 /// Iterates over all child modules. 94 /// Iterates over all child modules.
98 pub fn children_impl(&self, db: &impl HirDatabase) -> Cancelable<impl Iterator<Item = Module>> { 95 pub fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> {
99 // FIXME this should be implementable without collecting into a vec, but 96 // FIXME this should be implementable without collecting into a vec, but
100 // it's kind of hard since the iterator needs to keep a reference to the 97 // it's kind of hard since the iterator needs to keep a reference to the
101 // module tree. 98 // module tree.
@@ -106,42 +103,33 @@ impl Module {
106 .children(&module_tree) 103 .children(&module_tree)
107 .map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id)) 104 .map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id))
108 .collect::<Vec<_>>(); 105 .collect::<Vec<_>>();
109 Ok(children.into_iter()) 106 children.into_iter()
110 } 107 }
111 108
112 pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { 109 pub fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> {
113 let loc = self.def_id.loc(db); 110 let loc = self.def_id.loc(db);
114 let module_tree = db.module_tree(loc.source_root_id); 111 let module_tree = db.module_tree(loc.source_root_id);
115 let parent_id = ctry!(loc.module_id.parent(&module_tree)); 112 let parent_id = loc.module_id.parent(&module_tree)?;
116 Ok(Some(Module::from_module_id( 113 Some(Module::from_module_id(db, loc.source_root_id, parent_id))
117 db,
118 loc.source_root_id,
119 parent_id,
120 )))
121 } 114 }
122 115
123 /// Returns a `ModuleScope`: a set of items, visible in this module. 116 /// Returns a `ModuleScope`: a set of items, visible in this module.
124 pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { 117 pub fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope {
125 let loc = self.def_id.loc(db); 118 let loc = self.def_id.loc(db);
126 let item_map = db.item_map(loc.source_root_id)?; 119 let item_map = db.item_map(loc.source_root_id);
127 let res = item_map.per_module[&loc.module_id].clone(); 120 item_map.per_module[&loc.module_id].clone()
128 Ok(res)
129 } 121 }
130 122
131 pub fn resolve_path_impl( 123 pub fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> {
132 &self,
133 db: &impl HirDatabase,
134 path: &Path,
135 ) -> Cancelable<PerNs<DefId>> {
136 let mut curr_per_ns = PerNs::types( 124 let mut curr_per_ns = PerNs::types(
137 match path.kind { 125 match path.kind {
138 PathKind::Crate => self.crate_root(db)?, 126 PathKind::Crate => self.crate_root(db),
139 PathKind::Self_ | PathKind::Plain => self.clone(), 127 PathKind::Self_ | PathKind::Plain => self.clone(),
140 PathKind::Super => { 128 PathKind::Super => {
141 if let Some(p) = self.parent(db)? { 129 if let Some(p) = self.parent(db) {
142 p 130 p
143 } else { 131 } else {
144 return Ok(PerNs::none()); 132 return PerNs::none();
145 } 133 }
146 } 134 }
147 } 135 }
@@ -153,39 +141,39 @@ impl Module {
153 let curr = if let Some(r) = curr_per_ns.as_ref().take_types() { 141 let curr = if let Some(r) = curr_per_ns.as_ref().take_types() {
154 r 142 r
155 } else { 143 } else {
156 return Ok(PerNs::none()); 144 return PerNs::none();
157 }; 145 };
158 let module = match curr.resolve(db)? { 146 let module = match curr.resolve(db) {
159 Def::Module(it) => it, 147 Def::Module(it) => it,
160 Def::Enum(e) => { 148 Def::Enum(e) => {
161 if segments.len() == idx + 1 { 149 if segments.len() == idx + 1 {
162 // enum variant 150 // enum variant
163 let matching_variant = 151 let matching_variant =
164 e.variants(db)?.into_iter().find(|(n, _variant)| n == name); 152 e.variants(db).into_iter().find(|(n, _variant)| n == name);
165 153
166 if let Some((_n, variant)) = matching_variant { 154 if let Some((_n, variant)) = matching_variant {
167 return Ok(PerNs::both(variant.def_id(), e.def_id())); 155 return PerNs::both(variant.def_id(), e.def_id());
168 } else { 156 } else {
169 return Ok(PerNs::none()); 157 return PerNs::none();
170 } 158 }
171 } else if segments.len() == idx { 159 } else if segments.len() == idx {
172 // enum 160 // enum
173 return Ok(PerNs::types(e.def_id())); 161 return PerNs::types(e.def_id());
174 } else { 162 } else {
175 // malformed enum? 163 // malformed enum?
176 return Ok(PerNs::none()); 164 return PerNs::none();
177 } 165 }
178 } 166 }
179 _ => return Ok(PerNs::none()), 167 _ => return PerNs::none(),
180 }; 168 };
181 let scope = module.scope(db)?; 169 let scope = module.scope(db);
182 curr_per_ns = if let Some(r) = scope.get(&name) { 170 curr_per_ns = if let Some(r) = scope.get(&name) {
183 r.def_id 171 r.def_id
184 } else { 172 } else {
185 return Ok(PerNs::none()); 173 return PerNs::none();
186 }; 174 };
187 } 175 }
188 Ok(curr_per_ns) 176 curr_per_ns
189 } 177 }
190 178
191 pub fn problems_impl( 179 pub fn problems_impl(