diff options
Diffstat (limited to 'crates/ra_analysis/src/descriptors')
-rw-r--r-- | crates/ra_analysis/src/descriptors/mod.rs | 26 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 46 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/nameres.rs | 11 |
3 files changed, 74 insertions, 9 deletions
diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index 98094d9ee..7a1bcf447 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs | |||
@@ -13,9 +13,12 @@ use crate::{ | |||
13 | FileId, | 13 | FileId, |
14 | db::SyntaxDatabase, | 14 | db::SyntaxDatabase, |
15 | descriptors::function::{resolve_local_name, FnId, FnScopes}, | 15 | descriptors::function::{resolve_local_name, FnId, FnScopes}, |
16 | descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems, FileItems}}, | 16 | descriptors::module::{ |
17 | ModuleId, ModuleTree, ModuleSource, ModuleDescriptor, | ||
18 | nameres::{ItemMap, InputModuleItems, FileItems} | ||
19 | }, | ||
17 | input::SourceRootId, | 20 | input::SourceRootId, |
18 | loc2id::IdDatabase, | 21 | loc2id::{IdDatabase, DefId, DefLoc}, |
19 | syntax_ptr::LocalSyntaxPtr, | 22 | syntax_ptr::LocalSyntaxPtr, |
20 | Cancelable, | 23 | Cancelable, |
21 | }; | 24 | }; |
@@ -67,6 +70,25 @@ salsa::query_group! { | |||
67 | } | 70 | } |
68 | } | 71 | } |
69 | 72 | ||
73 | pub(crate) enum Def { | ||
74 | Module(ModuleDescriptor), | ||
75 | Item, | ||
76 | } | ||
77 | |||
78 | impl DefId { | ||
79 | pub(crate) fn resolve(self, db: &impl DescriptorDatabase) -> Cancelable<Def> { | ||
80 | let loc = db.id_maps().def_loc(self); | ||
81 | let res = match loc { | ||
82 | DefLoc::Module { id, source_root } => { | ||
83 | let descr = ModuleDescriptor::new(db, source_root, id)?; | ||
84 | Def::Module(descr) | ||
85 | } | ||
86 | DefLoc::Item { .. } => Def::Item, | ||
87 | }; | ||
88 | Ok(res) | ||
89 | } | ||
90 | } | ||
91 | |||
70 | #[derive(Debug)] | 92 | #[derive(Debug)] |
71 | pub struct ReferenceDescriptor { | 93 | pub struct ReferenceDescriptor { |
72 | pub range: TextRange, | 94 | pub range: TextRange, |
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index a6eaec178..78911d5d9 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs | |||
@@ -17,6 +17,7 @@ use crate::{ | |||
17 | descriptors::{Path, PathKind, DescriptorDatabase}, | 17 | descriptors::{Path, PathKind, DescriptorDatabase}, |
18 | input::SourceRootId, | 18 | input::SourceRootId, |
19 | arena::{Arena, Id}, | 19 | arena::{Arena, Id}, |
20 | loc2id::{DefLoc, DefId}, | ||
20 | }; | 21 | }; |
21 | 22 | ||
22 | pub(crate) use self::nameres::ModuleScope; | 23 | pub(crate) use self::nameres::ModuleScope; |
@@ -76,6 +77,20 @@ impl ModuleDescriptor { | |||
76 | Ok(res) | 77 | Ok(res) |
77 | } | 78 | } |
78 | 79 | ||
80 | pub(super) fn new( | ||
81 | db: &impl DescriptorDatabase, | ||
82 | source_root_id: SourceRootId, | ||
83 | module_id: ModuleId, | ||
84 | ) -> Cancelable<ModuleDescriptor> { | ||
85 | let module_tree = db._module_tree(source_root_id)?; | ||
86 | let res = ModuleDescriptor { | ||
87 | tree: module_tree, | ||
88 | source_root_id, | ||
89 | module_id, | ||
90 | }; | ||
91 | Ok(res) | ||
92 | } | ||
93 | |||
79 | /// Returns `mod foo;` or `mod foo {}` node whihc declared this module. | 94 | /// Returns `mod foo;` or `mod foo {}` node whihc declared this module. |
80 | /// Returns `None` for the root module | 95 | /// Returns `None` for the root module |
81 | pub fn parent_link_source( | 96 | pub fn parent_link_source( |
@@ -117,6 +132,14 @@ impl ModuleDescriptor { | |||
117 | Some(link.name(&self.tree)) | 132 | Some(link.name(&self.tree)) |
118 | } | 133 | } |
119 | 134 | ||
135 | pub fn def_id(&self, db: &impl DescriptorDatabase) -> DefId { | ||
136 | let def_loc = DefLoc::Module { | ||
137 | id: self.module_id, | ||
138 | source_root: self.source_root_id, | ||
139 | }; | ||
140 | db.id_maps().def_id(def_loc) | ||
141 | } | ||
142 | |||
120 | /// Finds a child module with the specified name. | 143 | /// Finds a child module with the specified name. |
121 | pub fn child(&self, name: &str) -> Option<ModuleDescriptor> { | 144 | pub fn child(&self, name: &str) -> Option<ModuleDescriptor> { |
122 | let child_id = self.module_id.child(&self.tree, name)?; | 145 | let child_id = self.module_id.child(&self.tree, name)?; |
@@ -133,17 +156,28 @@ impl ModuleDescriptor { | |||
133 | Ok(res) | 156 | Ok(res) |
134 | } | 157 | } |
135 | 158 | ||
136 | pub(crate) fn resolve_path(&self, path: Path) -> Option<ModuleDescriptor> { | 159 | pub(crate) fn resolve_path( |
160 | &self, | ||
161 | db: &impl DescriptorDatabase, | ||
162 | path: Path, | ||
163 | ) -> Cancelable<Option<DefId>> { | ||
137 | let mut curr = match path.kind { | 164 | let mut curr = match path.kind { |
138 | PathKind::Crate => self.crate_root(), | 165 | PathKind::Crate => self.crate_root(), |
139 | PathKind::Self_ | PathKind::Plain => self.clone(), | 166 | PathKind::Self_ | PathKind::Plain => self.clone(), |
140 | PathKind::Super => self.parent()?, | 167 | PathKind::Super => ctry!(self.parent()), |
141 | }; | 168 | } |
169 | .def_id(db); | ||
170 | |||
142 | let segments = path.segments; | 171 | let segments = path.segments; |
143 | for name in segments { | 172 | for name in segments.iter() { |
144 | curr = curr.child(&name)?; | 173 | let module = match db.id_maps().def_loc(curr) { |
174 | DefLoc::Module { id, source_root } => ModuleDescriptor::new(db, source_root, id)?, | ||
175 | _ => return Ok(None), | ||
176 | }; | ||
177 | let scope = module.scope(db)?; | ||
178 | curr = ctry!(ctry!(scope.get(&name)).def_id); | ||
145 | } | 179 | } |
146 | Some(curr) | 180 | Ok(Some(curr)) |
147 | } | 181 | } |
148 | 182 | ||
149 | pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> { | 183 | pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> { |
diff --git a/crates/ra_analysis/src/descriptors/module/nameres.rs b/crates/ra_analysis/src/descriptors/module/nameres.rs index d347a69b0..d2964f67f 100644 --- a/crates/ra_analysis/src/descriptors/module/nameres.rs +++ b/crates/ra_analysis/src/descriptors/module/nameres.rs | |||
@@ -103,7 +103,16 @@ pub(crate) struct ItemMap { | |||
103 | 103 | ||
104 | #[derive(Debug, Default, PartialEq, Eq, Clone)] | 104 | #[derive(Debug, Default, PartialEq, Eq, Clone)] |
105 | pub(crate) struct ModuleScope { | 105 | pub(crate) struct ModuleScope { |
106 | pub(crate) items: FxHashMap<SmolStr, Resolution>, | 106 | items: FxHashMap<SmolStr, Resolution>, |
107 | } | ||
108 | |||
109 | impl ModuleScope { | ||
110 | pub(crate) fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &Resolution)> + 'a { | ||
111 | self.items.iter() | ||
112 | } | ||
113 | pub(crate) fn get(&self, name: &SmolStr) -> Option<&Resolution> { | ||
114 | self.items.get(name) | ||
115 | } | ||
107 | } | 116 | } |
108 | 117 | ||
109 | /// A set of items and imports declared inside a module, without relation to | 118 | /// A set of items and imports declared inside a module, without relation to |