diff options
26 files changed, 366 insertions, 431 deletions
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs index b5d63e820..9825d52cf 100644 --- a/crates/ra_db/src/input.rs +++ b/crates/ra_db/src/input.rs | |||
@@ -160,6 +160,7 @@ pub trait FilesDatabase: salsa::Database { | |||
160 | /// Contents of the source root. | 160 | /// Contents of the source root. |
161 | #[salsa::input] | 161 | #[salsa::input] |
162 | fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; | 162 | fn source_root(&self, id: SourceRootId) -> Arc<SourceRoot>; |
163 | fn source_root_crates(&self, id: SourceRootId) -> Arc<Vec<CrateId>>; | ||
163 | /// The set of "local" (that is, from the current workspace) roots. | 164 | /// The set of "local" (that is, from the current workspace) roots. |
164 | /// Files in local roots are assumed to change frequently. | 165 | /// Files in local roots are assumed to change frequently. |
165 | #[salsa::input] | 166 | #[salsa::input] |
@@ -173,6 +174,17 @@ pub trait FilesDatabase: salsa::Database { | |||
173 | fn crate_graph(&self) -> Arc<CrateGraph>; | 174 | fn crate_graph(&self) -> Arc<CrateGraph>; |
174 | } | 175 | } |
175 | 176 | ||
177 | fn source_root_crates(db: &impl FilesDatabase, id: SourceRootId) -> Arc<Vec<CrateId>> { | ||
178 | let root = db.source_root(id); | ||
179 | let graph = db.crate_graph(); | ||
180 | let res = root | ||
181 | .files | ||
182 | .values() | ||
183 | .filter_map(|&it| graph.crate_id_for_crate_root(it)) | ||
184 | .collect::<Vec<_>>(); | ||
185 | Arc::new(res) | ||
186 | } | ||
187 | |||
176 | #[cfg(test)] | 188 | #[cfg(test)] |
177 | mod tests { | 189 | mod tests { |
178 | use super::{CrateGraph, FileId, SmolStr}; | 190 | use super::{CrateGraph, FileId, SmolStr}; |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 32d7e09b9..84759c75a 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -13,7 +13,7 @@ pub use crate::{ | |||
13 | cancellation::Canceled, | 13 | cancellation::Canceled, |
14 | input::{ | 14 | input::{ |
15 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, | 15 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, |
16 | FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery, | 16 | FileTextQuery, FileSourceRootQuery, SourceRootQuery, SourceRootCratesQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery, |
17 | FileRelativePathQuery | 17 | FileRelativePathQuery |
18 | }, | 18 | }, |
19 | loc2id::LocationIntener, | 19 | loc2id::LocationIntener, |
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index ab1c428db..4cca09351 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -64,9 +64,9 @@ fn get_def_id( | |||
64 | ..same_file_loc.source_item_id | 64 | ..same_file_loc.source_item_id |
65 | }; | 65 | }; |
66 | let loc = DefLoc { | 66 | let loc = DefLoc { |
67 | module: same_file_loc.module, | ||
67 | kind: expected_kind, | 68 | kind: expected_kind, |
68 | source_item_id, | 69 | source_item_id, |
69 | ..*same_file_loc | ||
70 | }; | 70 | }; |
71 | loc.id(db) | 71 | loc.id(db) |
72 | } | 72 | } |
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 3ff07bd60..f59a60c07 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -14,13 +14,14 @@ use crate::{ | |||
14 | adt::VariantData, | 14 | adt::VariantData, |
15 | generics::GenericParams, | 15 | generics::GenericParams, |
16 | code_model_impl::def_id_to_ast, | 16 | code_model_impl::def_id_to_ast, |
17 | docs::{Documentation, Docs, docs_from_ast} | 17 | docs::{Documentation, Docs, docs_from_ast}, |
18 | module_tree::ModuleId, | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | /// hir::Crate describes a single crate. It's the main interface with which | 21 | /// hir::Crate describes a single crate. It's the main interface with which |
21 | /// a crate's dependencies interact. Mostly, it should be just a proxy for the | 22 | /// a crate's dependencies interact. Mostly, it should be just a proxy for the |
22 | /// root module. | 23 | /// root module. |
23 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 24 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
24 | pub struct Crate { | 25 | pub struct Crate { |
25 | pub(crate) crate_id: CrateId, | 26 | pub(crate) crate_id: CrateId, |
26 | } | 27 | } |
@@ -45,7 +46,6 @@ impl Crate { | |||
45 | 46 | ||
46 | #[derive(Debug)] | 47 | #[derive(Debug)] |
47 | pub enum Def { | 48 | pub enum Def { |
48 | Module(Module), | ||
49 | Struct(Struct), | 49 | Struct(Struct), |
50 | Enum(Enum), | 50 | Enum(Enum), |
51 | EnumVariant(EnumVariant), | 51 | EnumVariant(EnumVariant), |
@@ -57,9 +57,29 @@ pub enum Def { | |||
57 | Item, | 57 | Item, |
58 | } | 58 | } |
59 | 59 | ||
60 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 60 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
61 | pub struct Module { | 61 | pub struct Module { |
62 | pub(crate) def_id: DefId, | 62 | pub(crate) krate: CrateId, |
63 | pub(crate) module_id: ModuleId, | ||
64 | } | ||
65 | |||
66 | /// The defs which can be visible in the module. | ||
67 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
68 | pub enum ModuleDef { | ||
69 | Module(Module), | ||
70 | Def(DefId), | ||
71 | } | ||
72 | |||
73 | impl Into<ModuleDef> for Module { | ||
74 | fn into(self) -> ModuleDef { | ||
75 | ModuleDef::Module(self) | ||
76 | } | ||
77 | } | ||
78 | |||
79 | impl Into<ModuleDef> for DefId { | ||
80 | fn into(self) -> ModuleDef { | ||
81 | ModuleDef::Def(self) | ||
82 | } | ||
63 | } | 83 | } |
64 | 84 | ||
65 | pub enum ModuleSource { | 85 | pub enum ModuleSource { |
@@ -149,7 +169,7 @@ impl Module { | |||
149 | self.scope_impl(db) | 169 | self.scope_impl(db) |
150 | } | 170 | } |
151 | 171 | ||
152 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { | 172 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> { |
153 | self.resolve_path_impl(db, path) | 173 | self.resolve_path_impl(db, path) |
154 | } | 174 | } |
155 | 175 | ||
diff --git a/crates/ra_hir/src/code_model_impl/krate.rs b/crates/ra_hir/src/code_model_impl/krate.rs index 8c6e34873..cdd30b402 100644 --- a/crates/ra_hir/src/code_model_impl/krate.rs +++ b/crates/ra_hir/src/code_model_impl/krate.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use ra_db::CrateId; | 1 | use ra_db::CrateId; |
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | HirFileId, Crate, CrateDependency, AsName, DefLoc, DefKind, Module, SourceItemId, | 4 | Crate, CrateDependency, AsName, Module, |
5 | db::HirDatabase, | 5 | db::HirDatabase, |
6 | }; | 6 | }; |
7 | 7 | ||
@@ -21,27 +21,13 @@ impl Crate { | |||
21 | .collect() | 21 | .collect() |
22 | } | 22 | } |
23 | pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> { | 23 | pub(crate) fn root_module_impl(&self, db: &impl HirDatabase) -> Option<Module> { |
24 | let crate_graph = db.crate_graph(); | 24 | let module_tree = db.module_tree(self.crate_id); |
25 | let file_id = crate_graph.crate_root(self.crate_id); | 25 | let module_id = module_tree.modules().next()?; |
26 | let source_root_id = db.file_source_root(file_id); | ||
27 | let file_id = HirFileId::from(file_id); | ||
28 | let module_tree = db.module_tree(source_root_id); | ||
29 | // FIXME: teach module tree about crate roots instead of guessing | ||
30 | let source = SourceItemId { | ||
31 | file_id, | ||
32 | item_id: None, | ||
33 | }; | ||
34 | let module_id = module_tree.find_module_by_source(source)?; | ||
35 | 26 | ||
36 | let def_loc = DefLoc { | 27 | let module = Module { |
37 | kind: DefKind::Module, | 28 | krate: self.crate_id, |
38 | source_root_id, | ||
39 | module_id, | 29 | module_id, |
40 | source_item_id: module_id.source(&module_tree), | ||
41 | }; | 30 | }; |
42 | let def_id = def_loc.id(db); | ||
43 | |||
44 | let module = Module::new(def_id); | ||
45 | Some(module) | 31 | Some(module) |
46 | } | 32 | } |
47 | } | 33 | } |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index d94079f11..5d00e905b 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -1,52 +1,33 @@ | |||
1 | use ra_db::{SourceRootId, FileId}; | 1 | use ra_db::FileId; |
2 | use ra_syntax::{ast, SyntaxNode, AstNode, TreeArc}; | 2 | use ra_syntax::{ast, SyntaxNode, TreeArc}; |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Problem, | 5 | Module, ModuleSource, Problem, ModuleDef, |
6 | Crate, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, | 6 | Crate, Name, Path, PathKind, PerNs, Def, |
7 | module_tree::ModuleId, | 7 | module_tree::ModuleId, |
8 | nameres::{ModuleScope, lower::ImportId}, | 8 | nameres::{ModuleScope, lower::ImportId}, |
9 | db::HirDatabase, | 9 | db::HirDatabase, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | impl Module { | 12 | impl Module { |
13 | pub(crate) fn new(def_id: DefId) -> Self { | 13 | fn with_module_id(&self, module_id: ModuleId) -> Module { |
14 | crate::code_model_api::Module { def_id } | 14 | Module { |
15 | } | ||
16 | |||
17 | pub(crate) fn from_module_id( | ||
18 | db: &impl HirDatabase, | ||
19 | source_root_id: SourceRootId, | ||
20 | module_id: ModuleId, | ||
21 | ) -> Self { | ||
22 | let module_tree = db.module_tree(source_root_id); | ||
23 | let def_loc = DefLoc { | ||
24 | kind: DefKind::Module, | ||
25 | source_root_id, | ||
26 | module_id, | 15 | module_id, |
27 | source_item_id: module_id.source(&module_tree), | 16 | krate: self.krate, |
28 | }; | 17 | } |
29 | let def_id = def_loc.id(db); | ||
30 | Module::new(def_id) | ||
31 | } | 18 | } |
32 | 19 | ||
33 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { | 20 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> { |
34 | let loc = self.def_id.loc(db); | 21 | let module_tree = db.module_tree(self.krate); |
35 | let module_tree = db.module_tree(loc.source_root_id); | 22 | let link = self.module_id.parent_link(&module_tree)?; |
36 | let link = loc.module_id.parent_link(&module_tree)?; | ||
37 | Some(link.name(&module_tree).clone()) | 23 | Some(link.name(&module_tree).clone()) |
38 | } | 24 | } |
39 | 25 | ||
40 | pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) { | 26 | pub(crate) fn definition_source_impl(&self, db: &impl HirDatabase) -> (FileId, ModuleSource) { |
41 | let loc = self.def_id.loc(db); | 27 | let module_tree = db.module_tree(self.krate); |
42 | let file_id = loc.source_item_id.file_id.as_original_file(); | 28 | let source = self.module_id.source(&module_tree); |
43 | let syntax_node = db.file_item(loc.source_item_id); | 29 | let module_source = ModuleSource::from_source_item_id(db, source); |
44 | let module_source = if let Some(source_file) = ast::SourceFile::cast(&syntax_node) { | 30 | let file_id = source.file_id.as_original_file(); |
45 | ModuleSource::SourceFile(source_file.to_owned()) | ||
46 | } else { | ||
47 | let module = ast::Module::cast(&syntax_node).unwrap(); | ||
48 | ModuleSource::Module(module.to_owned()) | ||
49 | }; | ||
50 | (file_id, module_source) | 31 | (file_id, module_source) |
51 | } | 32 | } |
52 | 33 | ||
@@ -54,9 +35,8 @@ impl Module { | |||
54 | &self, | 35 | &self, |
55 | db: &impl HirDatabase, | 36 | db: &impl HirDatabase, |
56 | ) -> Option<(FileId, TreeArc<ast::Module>)> { | 37 | ) -> Option<(FileId, TreeArc<ast::Module>)> { |
57 | let loc = self.def_id.loc(db); | 38 | let module_tree = db.module_tree(self.krate); |
58 | let module_tree = db.module_tree(loc.source_root_id); | 39 | let link = self.module_id.parent_link(&module_tree)?; |
59 | let link = loc.module_id.parent_link(&module_tree)?; | ||
60 | let file_id = link | 40 | let file_id = link |
61 | .owner(&module_tree) | 41 | .owner(&module_tree) |
62 | .source(&module_tree) | 42 | .source(&module_tree) |
@@ -71,85 +51,67 @@ impl Module { | |||
71 | db: &impl HirDatabase, | 51 | db: &impl HirDatabase, |
72 | import: ImportId, | 52 | import: ImportId, |
73 | ) -> TreeArc<ast::PathSegment> { | 53 | ) -> TreeArc<ast::PathSegment> { |
74 | let loc = self.def_id.loc(db); | 54 | let source_map = db.lower_module_source_map(self.clone()); |
75 | let source_map = db.lower_module_source_map(loc.source_root_id, loc.module_id); | ||
76 | let (_, source) = self.definition_source(db); | 55 | let (_, source) = self.definition_source(db); |
77 | source_map.get(&source, import) | 56 | source_map.get(&source, import) |
78 | } | 57 | } |
79 | 58 | ||
80 | pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Option<Crate> { | 59 | pub(crate) fn krate_impl(&self, _db: &impl HirDatabase) -> Option<Crate> { |
81 | let root = self.crate_root(db); | 60 | Some(Crate::new(self.krate)) |
82 | let loc = root.def_id.loc(db); | ||
83 | let file_id = loc.source_item_id.file_id.as_original_file(); | ||
84 | |||
85 | let crate_graph = db.crate_graph(); | ||
86 | let crate_id = crate_graph.crate_id_for_crate_root(file_id)?; | ||
87 | Some(Crate::new(crate_id)) | ||
88 | } | 61 | } |
89 | 62 | ||
90 | pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module { | 63 | pub(crate) fn crate_root_impl(&self, db: &impl HirDatabase) -> Module { |
91 | let loc = self.def_id.loc(db); | 64 | let module_tree = db.module_tree(self.krate); |
92 | let module_tree = db.module_tree(loc.source_root_id); | 65 | let module_id = self.module_id.crate_root(&module_tree); |
93 | let module_id = loc.module_id.crate_root(&module_tree); | 66 | self.with_module_id(module_id) |
94 | Module::from_module_id(db, loc.source_root_id, module_id) | ||
95 | } | 67 | } |
96 | 68 | ||
97 | /// Finds a child module with the specified name. | 69 | /// Finds a child module with the specified name. |
98 | pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { | 70 | pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { |
99 | let loc = self.def_id.loc(db); | 71 | let module_tree = db.module_tree(self.krate); |
100 | let module_tree = db.module_tree(loc.source_root_id); | 72 | let child_id = self.module_id.child(&module_tree, name)?; |
101 | let child_id = loc.module_id.child(&module_tree, name)?; | 73 | Some(self.with_module_id(child_id)) |
102 | Some(Module::from_module_id(db, loc.source_root_id, child_id)) | ||
103 | } | 74 | } |
104 | 75 | ||
105 | /// Iterates over all child modules. | 76 | /// Iterates over all child modules. |
106 | pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { | 77 | pub(crate) fn children_impl(&self, db: &impl HirDatabase) -> impl Iterator<Item = Module> { |
107 | // FIXME this should be implementable without collecting into a vec, but | 78 | let module_tree = db.module_tree(self.krate); |
108 | // it's kind of hard since the iterator needs to keep a reference to the | 79 | let children = self |
109 | // module tree. | ||
110 | let loc = self.def_id.loc(db); | ||
111 | let module_tree = db.module_tree(loc.source_root_id); | ||
112 | let children = loc | ||
113 | .module_id | 80 | .module_id |
114 | .children(&module_tree) | 81 | .children(&module_tree) |
115 | .map(|(_, module_id)| Module::from_module_id(db, loc.source_root_id, module_id)) | 82 | .map(|(_, module_id)| self.with_module_id(module_id)) |
116 | .collect::<Vec<_>>(); | 83 | .collect::<Vec<_>>(); |
117 | children.into_iter() | 84 | children.into_iter() |
118 | } | 85 | } |
119 | 86 | ||
120 | pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> { | 87 | pub(crate) fn parent_impl(&self, db: &impl HirDatabase) -> Option<Module> { |
121 | let loc = self.def_id.loc(db); | 88 | let module_tree = db.module_tree(self.krate); |
122 | let module_tree = db.module_tree(loc.source_root_id); | 89 | let parent_id = self.module_id.parent(&module_tree)?; |
123 | let parent_id = loc.module_id.parent(&module_tree)?; | 90 | Some(self.with_module_id(parent_id)) |
124 | Some(Module::from_module_id(db, loc.source_root_id, parent_id)) | ||
125 | } | 91 | } |
126 | 92 | ||
127 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 93 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
128 | pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope { | 94 | pub(crate) fn scope_impl(&self, db: &impl HirDatabase) -> ModuleScope { |
129 | let loc = self.def_id.loc(db); | 95 | let item_map = db.item_map(self.krate); |
130 | let item_map = db.item_map(loc.source_root_id); | 96 | item_map.per_module[&self.module_id].clone() |
131 | item_map.per_module[&loc.module_id].clone() | ||
132 | } | 97 | } |
133 | 98 | ||
134 | pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<DefId> { | 99 | pub(crate) fn resolve_path_impl(&self, db: &impl HirDatabase, path: &Path) -> PerNs<ModuleDef> { |
135 | let mut curr_per_ns = PerNs::types( | 100 | let mut curr_per_ns: PerNs<ModuleDef> = PerNs::types(match path.kind { |
136 | match path.kind { | 101 | PathKind::Crate => self.crate_root(db).into(), |
137 | PathKind::Crate => self.crate_root(db), | 102 | PathKind::Self_ | PathKind::Plain => self.clone().into(), |
138 | PathKind::Self_ | PathKind::Plain => self.clone(), | 103 | PathKind::Super => { |
139 | PathKind::Super => { | 104 | if let Some(p) = self.parent(db) { |
140 | if let Some(p) = self.parent(db) { | 105 | p.into() |
141 | p | 106 | } else { |
142 | } else { | ||
143 | return PerNs::none(); | ||
144 | } | ||
145 | } | ||
146 | PathKind::Abs => { | ||
147 | // TODO: absolute use is not supported | ||
148 | return PerNs::none(); | 107 | return PerNs::none(); |
149 | } | 108 | } |
150 | } | 109 | } |
151 | .def_id, | 110 | PathKind::Abs => { |
152 | ); | 111 | // TODO: absolute use is not supported |
112 | return PerNs::none(); | ||
113 | } | ||
114 | }); | ||
153 | 115 | ||
154 | for segment in path.segments.iter() { | 116 | for segment in path.segments.iter() { |
155 | let curr = match curr_per_ns.as_ref().take_types() { | 117 | let curr = match curr_per_ns.as_ref().take_types() { |
@@ -164,32 +126,39 @@ impl Module { | |||
164 | } | 126 | } |
165 | }; | 127 | }; |
166 | // resolve segment in curr | 128 | // resolve segment in curr |
167 | curr_per_ns = match curr.resolve(db) { | 129 | |
168 | Def::Module(m) => { | 130 | curr_per_ns = match curr { |
131 | ModuleDef::Module(m) => { | ||
169 | let scope = m.scope(db); | 132 | let scope = m.scope(db); |
170 | match scope.get(&segment.name) { | 133 | match scope.get(&segment.name) { |
171 | Some(r) => r.def_id, | 134 | Some(r) => r.def_id.clone(), |
172 | None => PerNs::none(), | 135 | None => PerNs::none(), |
173 | } | 136 | } |
174 | } | 137 | } |
175 | Def::Enum(e) => { | 138 | ModuleDef::Def(def) => { |
176 | // enum variant | 139 | match def.resolve(db) { |
177 | let matching_variant = e | 140 | Def::Enum(e) => { |
178 | .variants(db) | 141 | // enum variant |
179 | .into_iter() | 142 | let matching_variant = e |
180 | .find(|(n, _variant)| n == &segment.name); | 143 | .variants(db) |
181 | 144 | .into_iter() | |
182 | match matching_variant { | 145 | .find(|(n, _variant)| n == &segment.name); |
183 | Some((_n, variant)) => PerNs::both(variant.def_id(), e.def_id()), | 146 | |
184 | None => PerNs::none(), | 147 | match matching_variant { |
148 | Some((_n, variant)) => { | ||
149 | PerNs::both(variant.def_id().into(), e.def_id().into()) | ||
150 | } | ||
151 | None => PerNs::none(), | ||
152 | } | ||
153 | } | ||
154 | _ => { | ||
155 | // could be an inherent method call in UFCS form | ||
156 | // (`Struct::method`), or some other kind of associated | ||
157 | // item... Which we currently don't handle (TODO) | ||
158 | PerNs::none() | ||
159 | } | ||
185 | } | 160 | } |
186 | } | 161 | } |
187 | _ => { | ||
188 | // could be an inherent method call in UFCS form | ||
189 | // (`Struct::method`), or some other kind of associated | ||
190 | // item... Which we currently don't handle (TODO) | ||
191 | PerNs::none() | ||
192 | } | ||
193 | }; | 162 | }; |
194 | } | 163 | } |
195 | curr_per_ns | 164 | curr_per_ns |
@@ -199,8 +168,7 @@ impl Module { | |||
199 | &self, | 168 | &self, |
200 | db: &impl HirDatabase, | 169 | db: &impl HirDatabase, |
201 | ) -> Vec<(TreeArc<SyntaxNode>, Problem)> { | 170 | ) -> Vec<(TreeArc<SyntaxNode>, Problem)> { |
202 | let loc = self.def_id.loc(db); | 171 | let module_tree = db.module_tree(self.krate); |
203 | let module_tree = db.module_tree(loc.source_root_id); | 172 | self.module_id.problems(&module_tree, db) |
204 | loc.module_id.problems(&module_tree, db) | ||
205 | } | 173 | } |
206 | } | 174 | } |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index cc03da1e2..0898daa3c 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -1,15 +1,15 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; | 3 | use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; |
4 | use ra_db::{SourceRootId, SyntaxDatabase, salsa}; | 4 | use ra_db::{SyntaxDatabase, CrateId, salsa}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | HirInterner, DefId, MacroCallId, Name, HirFileId, | 7 | DefId, MacroCallId, Name, HirFileId, |
8 | SourceFileItems, SourceItemId, Crate, | 8 | SourceFileItems, SourceItemId, Crate, Module, HirInterner, |
9 | query_definitions, | 9 | query_definitions, |
10 | FnSignature, FnScopes, | 10 | FnSignature, FnScopes, |
11 | macros::MacroExpansion, | 11 | macros::MacroExpansion, |
12 | module_tree::{ModuleId, ModuleTree}, | 12 | module_tree::ModuleTree, |
13 | nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, | 13 | nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, |
14 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks}, | 14 | ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks}, |
15 | adt::{StructData, EnumData, EnumVariantData}, | 15 | adt::{StructData, EnumData, EnumVariantData}, |
@@ -56,38 +56,22 @@ pub trait HirDatabase: SyntaxDatabase + AsRef<HirInterner> { | |||
56 | fn submodules(&self, source: SourceItemId) -> Arc<Vec<crate::module_tree::Submodule>>; | 56 | fn submodules(&self, source: SourceItemId) -> Arc<Vec<crate::module_tree::Submodule>>; |
57 | 57 | ||
58 | #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)] | 58 | #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_query)] |
59 | fn lower_module( | 59 | fn lower_module(&self, module: Module) -> (Arc<LoweredModule>, Arc<ImportSourceMap>); |
60 | &self, | ||
61 | source_root_id: SourceRootId, | ||
62 | module_id: ModuleId, | ||
63 | ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>); | ||
64 | 60 | ||
65 | #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)] | 61 | #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_module_query)] |
66 | fn lower_module_module( | 62 | fn lower_module_module(&self, module: Module) -> Arc<LoweredModule>; |
67 | &self, | ||
68 | source_root_id: SourceRootId, | ||
69 | module_id: ModuleId, | ||
70 | ) -> Arc<LoweredModule>; | ||
71 | 63 | ||
72 | #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)] | 64 | #[salsa::invoke(crate::nameres::lower::LoweredModule::lower_module_source_map_query)] |
73 | fn lower_module_source_map( | 65 | fn lower_module_source_map(&self, module: Module) -> Arc<ImportSourceMap>; |
74 | &self, | ||
75 | source_root_id: SourceRootId, | ||
76 | module_id: ModuleId, | ||
77 | ) -> Arc<ImportSourceMap>; | ||
78 | 66 | ||
79 | #[salsa::invoke(query_definitions::item_map)] | 67 | #[salsa::invoke(query_definitions::item_map)] |
80 | fn item_map(&self, source_root_id: SourceRootId) -> Arc<ItemMap>; | 68 | fn item_map(&self, crate_id: CrateId) -> Arc<ItemMap>; |
81 | 69 | ||
82 | #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)] | 70 | #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)] |
83 | fn module_tree(&self, source_root_id: SourceRootId) -> Arc<ModuleTree>; | 71 | fn module_tree(&self, crate_id: CrateId) -> Arc<ModuleTree>; |
84 | 72 | ||
85 | #[salsa::invoke(crate::impl_block::impls_in_module)] | 73 | #[salsa::invoke(crate::impl_block::impls_in_module)] |
86 | fn impls_in_module( | 74 | fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>; |
87 | &self, | ||
88 | source_root_id: SourceRootId, | ||
89 | module_id: ModuleId, | ||
90 | ) -> Arc<ModuleImplBlocks>; | ||
91 | 75 | ||
92 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | 76 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] |
93 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | 77 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 43f0e81f9..99f04e4ef 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -1,11 +1,10 @@ | |||
1 | use ra_db::{SourceRootId, LocationIntener, FileId}; | 1 | use ra_db::{LocationIntener, FileId}; |
2 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; | 2 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; |
3 | use ra_arena::{Arena, RawId, impl_arena_id}; | 3 | use ra_arena::{Arena, RawId, impl_arena_id}; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate, | 6 | HirDatabase, Def, Function, Struct, Enum, EnumVariant, ImplBlock, Crate, |
7 | Module, Trait, Type, Static, Const, | 7 | Module, Trait, Type, Static, Const, |
8 | module_tree::ModuleId, | ||
9 | }; | 8 | }; |
10 | 9 | ||
11 | #[derive(Debug, Default)] | 10 | #[derive(Debug, Default)] |
@@ -110,10 +109,9 @@ impl From<MacroCallId> for HirFileId { | |||
110 | pub struct MacroCallId(RawId); | 109 | pub struct MacroCallId(RawId); |
111 | impl_arena_id!(MacroCallId); | 110 | impl_arena_id!(MacroCallId); |
112 | 111 | ||
113 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 112 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
114 | pub struct MacroCallLoc { | 113 | pub struct MacroCallLoc { |
115 | pub(crate) source_root_id: SourceRootId, | 114 | pub(crate) module: Module, |
116 | pub(crate) module_id: ModuleId, | ||
117 | pub(crate) source_item_id: SourceItemId, | 115 | pub(crate) source_item_id: SourceItemId, |
118 | } | 116 | } |
119 | 117 | ||
@@ -139,14 +137,12 @@ impl_arena_id!(DefId); | |||
139 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 137 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
140 | pub struct DefLoc { | 138 | pub struct DefLoc { |
141 | pub(crate) kind: DefKind, | 139 | pub(crate) kind: DefKind, |
142 | pub(crate) source_root_id: SourceRootId, | 140 | pub(crate) module: Module, |
143 | pub(crate) module_id: ModuleId, | ||
144 | pub(crate) source_item_id: SourceItemId, | 141 | pub(crate) source_item_id: SourceItemId, |
145 | } | 142 | } |
146 | 143 | ||
147 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 144 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
148 | pub(crate) enum DefKind { | 145 | pub(crate) enum DefKind { |
149 | Module, | ||
150 | Function, | 146 | Function, |
151 | Struct, | 147 | Struct, |
152 | Enum, | 148 | Enum, |
@@ -177,10 +173,6 @@ impl DefId { | |||
177 | pub fn resolve(self, db: &impl HirDatabase) -> Def { | 173 | pub fn resolve(self, db: &impl HirDatabase) -> Def { |
178 | let loc = self.loc(db); | 174 | let loc = self.loc(db); |
179 | match loc.kind { | 175 | match loc.kind { |
180 | DefKind::Module => { | ||
181 | let module = Module::from_module_id(db, loc.source_root_id, loc.module_id); | ||
182 | Def::Module(module) | ||
183 | } | ||
184 | DefKind::Function => { | 176 | DefKind::Function => { |
185 | let function = Function::new(self); | 177 | let function = Function::new(self); |
186 | Def::Function(function) | 178 | Def::Function(function) |
@@ -221,8 +213,7 @@ impl DefId { | |||
221 | 213 | ||
222 | /// For a module, returns that module; for any other def, returns the containing module. | 214 | /// For a module, returns that module; for any other def, returns the containing module. |
223 | pub fn module(self, db: &impl HirDatabase) -> Module { | 215 | pub fn module(self, db: &impl HirDatabase) -> Module { |
224 | let loc = self.loc(db); | 216 | self.loc(db).module |
225 | Module::from_module_id(db, loc.source_root_id, loc.module_id) | ||
226 | } | 217 | } |
227 | 218 | ||
228 | /// Returns the containing crate. | 219 | /// Returns the containing crate. |
@@ -232,8 +223,7 @@ impl DefId { | |||
232 | 223 | ||
233 | /// Returns the containing impl block, if this is an impl item. | 224 | /// Returns the containing impl block, if this is an impl item. |
234 | pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> { | 225 | pub fn impl_block(self, db: &impl HirDatabase) -> Option<ImplBlock> { |
235 | let loc = self.loc(db); | 226 | let module_impls = db.impls_in_module(self.loc(db).module); |
236 | let module_impls = db.impls_in_module(loc.source_root_id, loc.module_id); | ||
237 | ImplBlock::containing(module_impls, self) | 227 | ImplBlock::containing(module_impls, self) |
238 | } | 228 | } |
239 | } | 229 | } |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 551d0d149..ba8b84da2 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -3,14 +3,12 @@ use rustc_hash::FxHashMap; | |||
3 | 3 | ||
4 | use ra_arena::{Arena, RawId, impl_arena_id}; | 4 | use ra_arena::{Arena, RawId, impl_arena_id}; |
5 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
6 | use ra_db::{SourceRootId}; | ||
7 | 6 | ||
8 | use crate::{ | 7 | use crate::{ |
9 | DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, | 8 | DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, |
10 | Function, HirInterner, | 9 | Function, HirFileId, HirInterner, |
11 | db::HirDatabase, | 10 | db::HirDatabase, |
12 | type_ref::TypeRef, | 11 | type_ref::TypeRef, |
13 | module_tree::ModuleId, | ||
14 | }; | 12 | }; |
15 | 13 | ||
16 | use crate::code_model_api::{Module, ModuleSource}; | 14 | use crate::code_model_api::{Module, ModuleSource}; |
@@ -67,13 +65,13 @@ pub struct ImplData { | |||
67 | impl ImplData { | 65 | impl ImplData { |
68 | pub(crate) fn from_ast( | 66 | pub(crate) fn from_ast( |
69 | db: &impl AsRef<HirInterner>, | 67 | db: &impl AsRef<HirInterner>, |
68 | file_id: HirFileId, | ||
70 | file_items: &SourceFileItems, | 69 | file_items: &SourceFileItems, |
71 | module: &Module, | 70 | module: Module, |
72 | node: &ast::ImplBlock, | 71 | node: &ast::ImplBlock, |
73 | ) -> Self { | 72 | ) -> Self { |
74 | let target_trait = node.target_trait().map(TypeRef::from_ast); | 73 | let target_trait = node.target_trait().map(TypeRef::from_ast); |
75 | let target_type = TypeRef::from_ast_opt(node.target_type()); | 74 | let target_type = TypeRef::from_ast_opt(node.target_type()); |
76 | let module_loc = module.def_id.loc(db); | ||
77 | let items = if let Some(item_list) = node.item_list() { | 75 | let items = if let Some(item_list) = node.item_list() { |
78 | item_list | 76 | item_list |
79 | .impl_items() | 77 | .impl_items() |
@@ -85,13 +83,13 @@ impl ImplData { | |||
85 | }; | 83 | }; |
86 | let item_id = file_items.id_of_unchecked(item_node.syntax()); | 84 | let item_id = file_items.id_of_unchecked(item_node.syntax()); |
87 | let source_item_id = SourceItemId { | 85 | let source_item_id = SourceItemId { |
88 | file_id: module_loc.source_item_id.file_id, | 86 | file_id, |
89 | item_id: Some(item_id), | 87 | item_id: Some(item_id), |
90 | }; | 88 | }; |
91 | let def_loc = DefLoc { | 89 | let def_loc = DefLoc { |
90 | module, | ||
92 | kind, | 91 | kind, |
93 | source_item_id, | 92 | source_item_id, |
94 | ..module_loc | ||
95 | }; | 93 | }; |
96 | let def_id = def_loc.id(db); | 94 | let def_id = def_loc.id(db); |
97 | match item_node.kind() { | 95 | match item_node.kind() { |
@@ -168,6 +166,7 @@ impl ModuleImplBlocks { | |||
168 | 166 | ||
169 | fn collect(&mut self, db: &impl HirDatabase, module: Module) { | 167 | fn collect(&mut self, db: &impl HirDatabase, module: Module) { |
170 | let (file_id, module_source) = module.definition_source(db); | 168 | let (file_id, module_source) = module.definition_source(db); |
169 | let file_id: HirFileId = file_id.into(); | ||
171 | let node = match &module_source { | 170 | let node = match &module_source { |
172 | ModuleSource::SourceFile(node) => node.syntax(), | 171 | ModuleSource::SourceFile(node) => node.syntax(), |
173 | ModuleSource::Module(node) => node | 172 | ModuleSource::Module(node) => node |
@@ -176,10 +175,11 @@ impl ModuleImplBlocks { | |||
176 | .syntax(), | 175 | .syntax(), |
177 | }; | 176 | }; |
178 | 177 | ||
179 | let source_file_items = db.file_items(file_id.into()); | 178 | let source_file_items = db.file_items(file_id); |
180 | 179 | ||
181 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { | 180 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { |
182 | let impl_block = ImplData::from_ast(db, &source_file_items, &module, impl_block_ast); | 181 | let impl_block = |
182 | ImplData::from_ast(db, file_id, &source_file_items, module, impl_block_ast); | ||
183 | let id = self.impls.alloc(impl_block); | 183 | let id = self.impls.alloc(impl_block); |
184 | for impl_item in &self.impls[id].items { | 184 | for impl_item in &self.impls[id].items { |
185 | self.impls_by_def.insert(impl_item.def_id(), id); | 185 | self.impls_by_def.insert(impl_item.def_id(), id); |
@@ -188,13 +188,8 @@ impl ModuleImplBlocks { | |||
188 | } | 188 | } |
189 | } | 189 | } |
190 | 190 | ||
191 | pub(crate) fn impls_in_module( | 191 | pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> { |
192 | db: &impl HirDatabase, | ||
193 | source_root_id: SourceRootId, | ||
194 | module_id: ModuleId, | ||
195 | ) -> Arc<ModuleImplBlocks> { | ||
196 | let mut result = ModuleImplBlocks::new(); | 192 | let mut result = ModuleImplBlocks::new(); |
197 | let module = Module::from_module_id(db, source_root_id, module_id); | ||
198 | result.collect(db, module); | 193 | result.collect(db, module); |
199 | Arc::new(result) | 194 | Arc::new(result) |
200 | } | 195 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 87b5a8b8a..a6246a5e9 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -52,7 +52,7 @@ pub use self::{ | |||
52 | pub use self::code_model_api::{ | 52 | pub use self::code_model_api::{ |
53 | Crate, CrateDependency, | 53 | Crate, CrateDependency, |
54 | Def, | 54 | Def, |
55 | Module, ModuleSource, Problem, | 55 | Module, ModuleDef, ModuleSource, Problem, |
56 | Struct, Enum, EnumVariant, | 56 | Struct, Enum, EnumVariant, |
57 | Function, FnSignature, ScopeEntryWithSyntax, | 57 | Function, FnSignature, ScopeEntryWithSyntax, |
58 | StructField, | 58 | StructField, |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 4145c8048..361366f6a 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -35,10 +35,6 @@ impl MockDatabase { | |||
35 | let file_id = db.add_file(WORKSPACE, &mut source_root, "/main.rs", text); | 35 | let file_id = db.add_file(WORKSPACE, &mut source_root, "/main.rs", text); |
36 | db.query_mut(ra_db::SourceRootQuery) | 36 | db.query_mut(ra_db::SourceRootQuery) |
37 | .set(WORKSPACE, Arc::new(source_root.clone())); | 37 | .set(WORKSPACE, Arc::new(source_root.clone())); |
38 | |||
39 | let mut crate_graph = CrateGraph::default(); | ||
40 | crate_graph.add_crate_root(file_id); | ||
41 | db.set_crate_graph(crate_graph); | ||
42 | (db, source_root, file_id) | 38 | (db, source_root, file_id) |
43 | } | 39 | } |
44 | 40 | ||
@@ -97,6 +93,8 @@ impl MockDatabase { | |||
97 | text: &str, | 93 | text: &str, |
98 | ) -> FileId { | 94 | ) -> FileId { |
99 | assert!(path.starts_with('/')); | 95 | assert!(path.starts_with('/')); |
96 | let is_crate_root = path == "/lib.rs" || path == "/main.rs"; | ||
97 | |||
100 | let path = RelativePathBuf::from_path(&path[1..]).unwrap(); | 98 | let path = RelativePathBuf::from_path(&path[1..]).unwrap(); |
101 | let file_id = FileId(self.file_counter); | 99 | let file_id = FileId(self.file_counter); |
102 | self.file_counter += 1; | 100 | self.file_counter += 1; |
@@ -107,6 +105,12 @@ impl MockDatabase { | |||
107 | self.query_mut(ra_db::FileSourceRootQuery) | 105 | self.query_mut(ra_db::FileSourceRootQuery) |
108 | .set(file_id, source_root_id); | 106 | .set(file_id, source_root_id); |
109 | source_root.files.insert(path, file_id); | 107 | source_root.files.insert(path, file_id); |
108 | |||
109 | if is_crate_root { | ||
110 | let mut crate_graph = CrateGraph::default(); | ||
111 | crate_graph.add_crate_root(file_id); | ||
112 | self.set_crate_graph(crate_graph); | ||
113 | } | ||
110 | file_id | 114 | file_id |
111 | } | 115 | } |
112 | 116 | ||
@@ -202,6 +206,7 @@ salsa::database_storage! { | |||
202 | fn file_relative_path() for ra_db::FileRelativePathQuery; | 206 | fn file_relative_path() for ra_db::FileRelativePathQuery; |
203 | fn file_source_root() for ra_db::FileSourceRootQuery; | 207 | fn file_source_root() for ra_db::FileSourceRootQuery; |
204 | fn source_root() for ra_db::SourceRootQuery; | 208 | fn source_root() for ra_db::SourceRootQuery; |
209 | fn source_root_crates() for ra_db::SourceRootCratesQuery; | ||
205 | fn local_roots() for ra_db::LocalRootsQuery; | 210 | fn local_roots() for ra_db::LocalRootsQuery; |
206 | fn library_roots() for ra_db::LibraryRootsQuery; | 211 | fn library_roots() for ra_db::LibraryRootsQuery; |
207 | fn crate_graph() for ra_db::CrateGraphQuery; | 212 | fn crate_graph() for ra_db::CrateGraphQuery; |
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index b201bf69b..c00834c4c 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | use arrayvec::ArrayVec; | 4 | use arrayvec::ArrayVec; |
5 | use relative_path::RelativePathBuf; | 5 | use relative_path::RelativePathBuf; |
6 | use ra_db::{FileId, SourceRootId, SourceRoot}; | 6 | use ra_db::{FileId, SourceRoot, CrateId}; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | SyntaxNode, TreeArc, | 8 | SyntaxNode, TreeArc, |
9 | algo::generate, | 9 | algo::generate, |
@@ -126,13 +126,10 @@ struct LinkData { | |||
126 | } | 126 | } |
127 | 127 | ||
128 | impl ModuleTree { | 128 | impl ModuleTree { |
129 | pub(crate) fn module_tree_query( | 129 | pub(crate) fn module_tree_query(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ModuleTree> { |
130 | db: &impl HirDatabase, | ||
131 | source_root: SourceRootId, | ||
132 | ) -> Arc<ModuleTree> { | ||
133 | db.check_canceled(); | 130 | db.check_canceled(); |
134 | let mut res = ModuleTree::default(); | 131 | let mut res = ModuleTree::default(); |
135 | res.init(db, source_root); | 132 | res.init_crate(db, crate_id); |
136 | Arc::new(res) | 133 | Arc::new(res) |
137 | } | 134 | } |
138 | 135 | ||
@@ -145,24 +142,21 @@ impl ModuleTree { | |||
145 | Some(res) | 142 | Some(res) |
146 | } | 143 | } |
147 | 144 | ||
148 | fn init(&mut self, db: &impl HirDatabase, source_root: SourceRootId) { | 145 | fn init_crate(&mut self, db: &impl HirDatabase, crate_id: CrateId) { |
146 | let crate_graph = db.crate_graph(); | ||
147 | let file_id = crate_graph.crate_root(crate_id); | ||
148 | let source_root_id = db.file_source_root(file_id); | ||
149 | |||
149 | let mut roots = FxHashMap::default(); | 150 | let mut roots = FxHashMap::default(); |
150 | let mut visited = FxHashSet::default(); | 151 | let mut visited = FxHashSet::default(); |
151 | 152 | ||
152 | let source_root = db.source_root(source_root); | 153 | let source_root = db.source_root(source_root_id); |
153 | for &file_id in source_root.files.values() { | 154 | let source = SourceItemId { |
154 | let source = SourceItemId { | 155 | file_id: file_id.into(), |
155 | file_id: file_id.into(), | 156 | item_id: None, |
156 | item_id: None, | 157 | }; |
157 | }; | 158 | let module_id = self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source); |
158 | if visited.contains(&source) { | 159 | roots.insert(file_id, module_id); |
159 | continue; // TODO: use explicit crate_roots here | ||
160 | } | ||
161 | assert!(!roots.contains_key(&file_id)); | ||
162 | let module_id = | ||
163 | self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source); | ||
164 | roots.insert(file_id, module_id); | ||
165 | } | ||
166 | } | 160 | } |
167 | 161 | ||
168 | fn init_subtree( | 162 | fn init_subtree( |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 1d163edf7..a3bc98958 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -16,19 +16,19 @@ | |||
16 | //! structure itself is modified. | 16 | //! structure itself is modified. |
17 | pub(crate) mod lower; | 17 | pub(crate) mod lower; |
18 | 18 | ||
19 | use crate::nameres::lower::*; | ||
20 | |||
21 | use std::sync::Arc; | 19 | use std::sync::Arc; |
22 | 20 | ||
21 | use ra_db::CrateId; | ||
23 | use rustc_hash::{FxHashMap, FxHashSet}; | 22 | use rustc_hash::{FxHashMap, FxHashSet}; |
24 | use ra_db::SourceRootId; | ||
25 | 23 | ||
26 | use crate::{ | 24 | use crate::{ |
27 | DefId, DefLoc, DefKind, | 25 | Module, ModuleDef, |
28 | Path, PathKind, | 26 | Path, PathKind, |
29 | HirDatabase, Crate, | 27 | HirDatabase, Crate, |
30 | Name, | 28 | Name, |
31 | module_tree::{ModuleId, ModuleTree}, | 29 | module_tree::{ModuleId, ModuleTree}, |
30 | //FIXME: deglobify | ||
31 | nameres::lower::*, | ||
32 | }; | 32 | }; |
33 | 33 | ||
34 | /// `ItemMap` is the result of name resolution. It contains, for each | 34 | /// `ItemMap` is the result of name resolution. It contains, for each |
@@ -58,7 +58,7 @@ impl ModuleScope { | |||
58 | #[derive(Debug, Clone, PartialEq, Eq)] | 58 | #[derive(Debug, Clone, PartialEq, Eq)] |
59 | pub struct Resolution { | 59 | pub struct Resolution { |
60 | /// None for unresolved | 60 | /// None for unresolved |
61 | pub def_id: PerNs<DefId>, | 61 | pub def_id: PerNs<ModuleDef>, |
62 | /// ident by which this is imported into local scope. | 62 | /// ident by which this is imported into local scope. |
63 | pub import: Option<ImportId>, | 63 | pub import: Option<ImportId>, |
64 | } | 64 | } |
@@ -152,7 +152,7 @@ impl<T> PerNs<T> { | |||
152 | pub(crate) struct Resolver<'a, DB> { | 152 | pub(crate) struct Resolver<'a, DB> { |
153 | db: &'a DB, | 153 | db: &'a DB, |
154 | input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>, | 154 | input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>, |
155 | source_root: SourceRootId, | 155 | krate: CrateId, |
156 | module_tree: Arc<ModuleTree>, | 156 | module_tree: Arc<ModuleTree>, |
157 | processed_imports: FxHashSet<(ModuleId, ImportId)>, | 157 | processed_imports: FxHashSet<(ModuleId, ImportId)>, |
158 | result: ItemMap, | 158 | result: ItemMap, |
@@ -165,13 +165,13 @@ where | |||
165 | pub(crate) fn new( | 165 | pub(crate) fn new( |
166 | db: &'a DB, | 166 | db: &'a DB, |
167 | input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>, | 167 | input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>, |
168 | source_root: SourceRootId, | 168 | krate: CrateId, |
169 | module_tree: Arc<ModuleTree>, | ||
170 | ) -> Resolver<'a, DB> { | 169 | ) -> Resolver<'a, DB> { |
170 | let module_tree = db.module_tree(krate); | ||
171 | Resolver { | 171 | Resolver { |
172 | db, | 172 | db, |
173 | input, | 173 | input, |
174 | source_root, | 174 | krate, |
175 | module_tree, | 175 | module_tree, |
176 | processed_imports: FxHashSet::default(), | 176 | processed_imports: FxHashSet::default(), |
177 | result: ItemMap::default(), | 177 | result: ItemMap::default(), |
@@ -210,7 +210,7 @@ where | |||
210 | let krate = Crate::new(crate_id); | 210 | let krate = Crate::new(crate_id); |
211 | for dep in krate.dependencies(self.db) { | 211 | for dep in krate.dependencies(self.db) { |
212 | if let Some(module) = dep.krate.root_module(self.db) { | 212 | if let Some(module) = dep.krate.root_module(self.db) { |
213 | let def_id = module.def_id; | 213 | let def_id = module.into(); |
214 | self.add_module_item( | 214 | self.add_module_item( |
215 | &mut module_items, | 215 | &mut module_items, |
216 | dep.name.clone(), | 216 | dep.name.clone(), |
@@ -244,20 +244,22 @@ where | |||
244 | 244 | ||
245 | // Populate modules | 245 | // Populate modules |
246 | for (name, module_id) in module_id.children(&self.module_tree) { | 246 | for (name, module_id) in module_id.children(&self.module_tree) { |
247 | let def_loc = DefLoc { | 247 | let module = Module { |
248 | kind: DefKind::Module, | ||
249 | source_root_id: self.source_root, | ||
250 | module_id, | 248 | module_id, |
251 | source_item_id: module_id.source(&self.module_tree), | 249 | krate: self.krate, |
252 | }; | 250 | }; |
253 | let def_id = def_loc.id(self.db); | 251 | self.add_module_item(&mut module_items, name, PerNs::types(module.into())); |
254 | self.add_module_item(&mut module_items, name, PerNs::types(def_id)); | ||
255 | } | 252 | } |
256 | 253 | ||
257 | self.result.per_module.insert(module_id, module_items); | 254 | self.result.per_module.insert(module_id, module_items); |
258 | } | 255 | } |
259 | 256 | ||
260 | fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def_id: PerNs<DefId>) { | 257 | fn add_module_item( |
258 | &self, | ||
259 | module_items: &mut ModuleScope, | ||
260 | name: Name, | ||
261 | def_id: PerNs<ModuleDef>, | ||
262 | ) { | ||
261 | let resolution = Resolution { | 263 | let resolution = Resolution { |
262 | def_id, | 264 | def_id, |
263 | import: None, | 265 | import: None, |
@@ -329,17 +331,11 @@ where | |||
329 | ); | 331 | ); |
330 | return false; | 332 | return false; |
331 | }; | 333 | }; |
332 | curr = match type_def_id.loc(self.db) { | 334 | curr = match type_def_id { |
333 | DefLoc { | 335 | ModuleDef::Module(module) => { |
334 | kind: DefKind::Module, | 336 | if module.krate == self.krate { |
335 | module_id: target_module_id, | 337 | module.module_id |
336 | source_root_id, | ||
337 | .. | ||
338 | } => { | ||
339 | if source_root_id == self.source_root { | ||
340 | target_module_id | ||
341 | } else { | 338 | } else { |
342 | let module = crate::code_model_api::Module::new(type_def_id); | ||
343 | let path = Path { | 339 | let path = Path { |
344 | segments: import.path.segments[i + 1..].iter().cloned().collect(), | 340 | segments: import.path.segments[i + 1..].iter().cloned().collect(), |
345 | kind: PathKind::Crate, | 341 | kind: PathKind::Crate, |
@@ -359,7 +355,7 @@ where | |||
359 | "resolved import {:?} ({:?}) cross-source root to {:?}", | 355 | "resolved import {:?} ({:?}) cross-source root to {:?}", |
360 | last_segment.name, | 356 | last_segment.name, |
361 | import, | 357 | import, |
362 | def_id.map(|did| did.loc(self.db)) | 358 | def_id, |
363 | ); | 359 | ); |
364 | return true; | 360 | return true; |
365 | } else { | 361 | } else { |
@@ -372,7 +368,7 @@ where | |||
372 | log::debug!( | 368 | log::debug!( |
373 | "path segment {:?} resolved to non-module {:?}, but is not last", | 369 | "path segment {:?} resolved to non-module {:?}, but is not last", |
374 | segment.name, | 370 | segment.name, |
375 | type_def_id.loc(self.db) | 371 | type_def_id, |
376 | ); | 372 | ); |
377 | return true; // this resolved to a non-module, so the path won't ever resolve | 373 | return true; // this resolved to a non-module, so the path won't ever resolve |
378 | } | 374 | } |
@@ -382,7 +378,7 @@ where | |||
382 | "resolved import {:?} ({:?}) within source root to {:?}", | 378 | "resolved import {:?} ({:?}) within source root to {:?}", |
383 | segment.name, | 379 | segment.name, |
384 | import, | 380 | import, |
385 | def_id.map(|did| did.loc(self.db)) | 381 | def_id, |
386 | ); | 382 | ); |
387 | self.update(module_id, |items| { | 383 | self.update(module_id, |items| { |
388 | let res = Resolution { | 384 | let res = Resolution { |
diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index 4eea6ff1d..6f003bd66 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs | |||
@@ -4,14 +4,13 @@ use ra_syntax::{ | |||
4 | SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr, | 4 | SyntaxKind, AstNode, SourceFile, TreeArc, AstPtr, |
5 | ast::{self, ModuleItemOwner, NameOwner}, | 5 | ast::{self, ModuleItemOwner, NameOwner}, |
6 | }; | 6 | }; |
7 | use ra_db::SourceRootId; | ||
8 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 7 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
9 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
10 | 9 | ||
11 | use crate::{ | 10 | use crate::{ |
12 | SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, | 11 | SourceItemId, Path, ModuleSource, HirDatabase, Name, SourceFileItems, |
13 | HirFileId, MacroCallLoc, AsName, PerNs, DefId, DefKind, DefLoc, | 12 | HirFileId, MacroCallLoc, AsName, PerNs, DefKind, DefLoc, |
14 | module_tree::ModuleId | 13 | ModuleDef, Module, |
15 | }; | 14 | }; |
16 | 15 | ||
17 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 16 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -32,7 +31,7 @@ pub(super) struct ImportData { | |||
32 | /// can avoid redoing name resolution. | 31 | /// can avoid redoing name resolution. |
33 | #[derive(Debug, Default, PartialEq, Eq)] | 32 | #[derive(Debug, Default, PartialEq, Eq)] |
34 | pub struct LoweredModule { | 33 | pub struct LoweredModule { |
35 | pub(crate) declarations: FxHashMap<Name, PerNs<DefId>>, | 34 | pub(crate) declarations: FxHashMap<Name, PerNs<ModuleDef>>, |
36 | pub(super) imports: Arena<ImportId, ImportData>, | 35 | pub(super) imports: Arena<ImportId, ImportData>, |
37 | } | 36 | } |
38 | 37 | ||
@@ -59,37 +58,31 @@ impl ImportSourceMap { | |||
59 | impl LoweredModule { | 58 | impl LoweredModule { |
60 | pub(crate) fn lower_module_module_query( | 59 | pub(crate) fn lower_module_module_query( |
61 | db: &impl HirDatabase, | 60 | db: &impl HirDatabase, |
62 | source_root_id: SourceRootId, | 61 | module: Module, |
63 | module_id: ModuleId, | ||
64 | ) -> Arc<LoweredModule> { | 62 | ) -> Arc<LoweredModule> { |
65 | db.lower_module(source_root_id, module_id).0 | 63 | db.lower_module(module).0 |
66 | } | 64 | } |
67 | 65 | ||
68 | pub(crate) fn lower_module_source_map_query( | 66 | pub(crate) fn lower_module_source_map_query( |
69 | db: &impl HirDatabase, | 67 | db: &impl HirDatabase, |
70 | source_root_id: SourceRootId, | 68 | module: Module, |
71 | module_id: ModuleId, | ||
72 | ) -> Arc<ImportSourceMap> { | 69 | ) -> Arc<ImportSourceMap> { |
73 | db.lower_module(source_root_id, module_id).1 | 70 | db.lower_module(module).1 |
74 | } | 71 | } |
75 | 72 | ||
76 | pub(crate) fn lower_module_query( | 73 | pub(crate) fn lower_module_query( |
77 | db: &impl HirDatabase, | 74 | db: &impl HirDatabase, |
78 | source_root_id: SourceRootId, | 75 | module: Module, |
79 | module_id: ModuleId, | ||
80 | ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) { | 76 | ) -> (Arc<LoweredModule>, Arc<ImportSourceMap>) { |
81 | let module_tree = db.module_tree(source_root_id); | 77 | let (file_id, source) = module.definition_source(db); |
82 | let source = module_id.source(&module_tree); | 78 | let file_id: HirFileId = file_id.into(); |
83 | let file_id = source.file_id; | ||
84 | let source = ModuleSource::from_source_item_id(db, source); | ||
85 | let mut source_map = ImportSourceMap::default(); | 79 | let mut source_map = ImportSourceMap::default(); |
86 | let mut res = LoweredModule::default(); | 80 | let mut res = LoweredModule::default(); |
87 | match source { | 81 | match source { |
88 | ModuleSource::SourceFile(it) => res.fill( | 82 | ModuleSource::SourceFile(it) => res.fill( |
89 | &mut source_map, | 83 | &mut source_map, |
90 | db, | 84 | db, |
91 | source_root_id, | 85 | module, |
92 | module_id, | ||
93 | file_id, | 86 | file_id, |
94 | &mut it.items_with_macros(), | 87 | &mut it.items_with_macros(), |
95 | ), | 88 | ), |
@@ -98,8 +91,7 @@ impl LoweredModule { | |||
98 | res.fill( | 91 | res.fill( |
99 | &mut source_map, | 92 | &mut source_map, |
100 | db, | 93 | db, |
101 | source_root_id, | 94 | module, |
102 | module_id, | ||
103 | file_id, | 95 | file_id, |
104 | &mut item_list.items_with_macros(), | 96 | &mut item_list.items_with_macros(), |
105 | ) | 97 | ) |
@@ -113,8 +105,7 @@ impl LoweredModule { | |||
113 | &mut self, | 105 | &mut self, |
114 | source_map: &mut ImportSourceMap, | 106 | source_map: &mut ImportSourceMap, |
115 | db: &impl HirDatabase, | 107 | db: &impl HirDatabase, |
116 | source_root_id: SourceRootId, | 108 | module: Module, |
117 | module_id: ModuleId, | ||
118 | file_id: HirFileId, | 109 | file_id: HirFileId, |
119 | items: &mut Iterator<Item = ast::ItemOrMacro>, | 110 | items: &mut Iterator<Item = ast::ItemOrMacro>, |
120 | ) { | 111 | ) { |
@@ -123,21 +114,12 @@ impl LoweredModule { | |||
123 | for item in items { | 114 | for item in items { |
124 | match item { | 115 | match item { |
125 | ast::ItemOrMacro::Item(it) => { | 116 | ast::ItemOrMacro::Item(it) => { |
126 | self.add_def_id( | 117 | self.add_def_id(source_map, db, module, file_id, &file_items, it); |
127 | source_map, | ||
128 | db, | ||
129 | source_root_id, | ||
130 | module_id, | ||
131 | file_id, | ||
132 | &file_items, | ||
133 | it, | ||
134 | ); | ||
135 | } | 118 | } |
136 | ast::ItemOrMacro::Macro(macro_call) => { | 119 | ast::ItemOrMacro::Macro(macro_call) => { |
137 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); | 120 | let item_id = file_items.id_of_unchecked(macro_call.syntax()); |
138 | let loc = MacroCallLoc { | 121 | let loc = MacroCallLoc { |
139 | source_root_id, | 122 | module, |
140 | module_id, | ||
141 | source_item_id: SourceItemId { | 123 | source_item_id: SourceItemId { |
142 | file_id, | 124 | file_id, |
143 | item_id: Some(item_id), | 125 | item_id: Some(item_id), |
@@ -148,15 +130,7 @@ impl LoweredModule { | |||
148 | let file_items = db.file_items(file_id); | 130 | let file_items = db.file_items(file_id); |
149 | //FIXME: expand recursively | 131 | //FIXME: expand recursively |
150 | for item in db.hir_source_file(file_id).items() { | 132 | for item in db.hir_source_file(file_id).items() { |
151 | self.add_def_id( | 133 | self.add_def_id(source_map, db, module, file_id, &file_items, item); |
152 | source_map, | ||
153 | db, | ||
154 | source_root_id, | ||
155 | module_id, | ||
156 | file_id, | ||
157 | &file_items, | ||
158 | item, | ||
159 | ); | ||
160 | } | 134 | } |
161 | } | 135 | } |
162 | } | 136 | } |
@@ -167,8 +141,7 @@ impl LoweredModule { | |||
167 | &mut self, | 141 | &mut self, |
168 | source_map: &mut ImportSourceMap, | 142 | source_map: &mut ImportSourceMap, |
169 | db: &impl HirDatabase, | 143 | db: &impl HirDatabase, |
170 | source_root_id: SourceRootId, | 144 | module: Module, |
171 | module_id: ModuleId, | ||
172 | file_id: HirFileId, | 145 | file_id: HirFileId, |
173 | file_items: &SourceFileItems, | 146 | file_items: &SourceFileItems, |
174 | item: &ast::ModuleItem, | 147 | item: &ast::ModuleItem, |
@@ -199,7 +172,7 @@ impl LoweredModule { | |||
199 | } | 172 | } |
200 | }; | 173 | }; |
201 | if let Some(name) = name { | 174 | if let Some(name) = name { |
202 | let def_id = assign_def_id(db, source_root_id, module_id, file_id, file_items, item); | 175 | let def_id = assign_def_id(db, module, file_id, file_items, item); |
203 | self.declarations.insert(name.as_name(), def_id); | 176 | self.declarations.insert(name.as_name(), def_id); |
204 | } | 177 | } |
205 | } | 178 | } |
@@ -219,12 +192,11 @@ impl LoweredModule { | |||
219 | 192 | ||
220 | fn assign_def_id( | 193 | fn assign_def_id( |
221 | db: &impl HirDatabase, | 194 | db: &impl HirDatabase, |
222 | source_root_id: SourceRootId, | 195 | module: Module, |
223 | module_id: ModuleId, | ||
224 | file_id: HirFileId, | 196 | file_id: HirFileId, |
225 | file_items: &SourceFileItems, | 197 | file_items: &SourceFileItems, |
226 | item: &ast::ModuleItem, | 198 | item: &ast::ModuleItem, |
227 | ) -> PerNs<DefId> { | 199 | ) -> PerNs<ModuleDef> { |
228 | // depending on the item kind, the location can define something in | 200 | // depending on the item kind, the location can define something in |
229 | // the values namespace, the types namespace, or both | 201 | // the values namespace, the types namespace, or both |
230 | let kind = DefKind::for_syntax_kind(item.syntax().kind()); | 202 | let kind = DefKind::for_syntax_kind(item.syntax().kind()); |
@@ -232,14 +204,13 @@ fn assign_def_id( | |||
232 | let item_id = file_items.id_of_unchecked(item.syntax()); | 204 | let item_id = file_items.id_of_unchecked(item.syntax()); |
233 | let def_loc = DefLoc { | 205 | let def_loc = DefLoc { |
234 | kind: k, | 206 | kind: k, |
235 | source_root_id, | 207 | module, |
236 | module_id, | ||
237 | source_item_id: SourceItemId { | 208 | source_item_id: SourceItemId { |
238 | file_id, | 209 | file_id, |
239 | item_id: Some(item_id), | 210 | item_id: Some(item_id), |
240 | }, | 211 | }, |
241 | }; | 212 | }; |
242 | def_loc.id(db) | 213 | def_loc.id(db).into() |
243 | }); | 214 | }); |
244 | def_id | 215 | def_id |
245 | } | 216 | } |
@@ -248,7 +219,6 @@ impl DefKind { | |||
248 | fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> { | 219 | fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> { |
249 | match kind { | 220 | match kind { |
250 | SyntaxKind::FN_DEF => PerNs::values(DefKind::Function), | 221 | SyntaxKind::FN_DEF => PerNs::values(DefKind::Function), |
251 | SyntaxKind::MODULE => PerNs::types(DefKind::Module), | ||
252 | SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor), | 222 | SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor), |
253 | SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum), | 223 | SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum), |
254 | SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait), | 224 | SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Trait), |
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index e92007453..9322bf08c 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_db::{FilesDatabase, CrateGraph, SourceRootId, salsa::Database}; | 3 | use ra_db::{CrateGraph, SourceRootId, salsa::Database}; |
4 | use relative_path::RelativePath; | 4 | use relative_path::RelativePath; |
5 | use test_utils::{assert_eq_text, covers}; | 5 | use test_utils::{assert_eq_text, covers}; |
6 | 6 | ||
@@ -13,10 +13,10 @@ use crate::{ | |||
13 | 13 | ||
14 | fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) { | 14 | fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) { |
15 | let (db, pos) = MockDatabase::with_position(fixture); | 15 | let (db, pos) = MockDatabase::with_position(fixture); |
16 | let source_root = db.file_source_root(pos.file_id); | ||
17 | let module = crate::source_binder::module_from_position(&db, pos).unwrap(); | 16 | let module = crate::source_binder::module_from_position(&db, pos).unwrap(); |
18 | let module_id = module.def_id.loc(&db).module_id; | 17 | let krate = module.krate(&db).unwrap(); |
19 | (db.item_map(source_root), module_id) | 18 | let module_id = module.module_id; |
19 | (db.item_map(krate.crate_id), module_id) | ||
20 | } | 20 | } |
21 | 21 | ||
22 | fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { | 22 | fn check_module_item_map(map: &ItemMap, module_id: ModuleId, expected: &str) { |
@@ -238,14 +238,13 @@ fn item_map_across_crates() { | |||
238 | 238 | ||
239 | db.set_crate_graph(crate_graph); | 239 | db.set_crate_graph(crate_graph); |
240 | 240 | ||
241 | let source_root = db.file_source_root(main_id); | ||
242 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | 241 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); |
243 | let module_id = module.def_id.loc(&db).module_id; | 242 | let krate = module.krate(&db).unwrap(); |
244 | let item_map = db.item_map(source_root); | 243 | let item_map = db.item_map(krate.crate_id); |
245 | 244 | ||
246 | check_module_item_map( | 245 | check_module_item_map( |
247 | &item_map, | 246 | &item_map, |
248 | module_id, | 247 | module.module_id, |
249 | " | 248 | " |
250 | Baz: t v | 249 | Baz: t v |
251 | test_crate: t | 250 | test_crate: t |
@@ -292,12 +291,12 @@ fn import_across_source_roots() { | |||
292 | db.set_crate_graph(crate_graph); | 291 | db.set_crate_graph(crate_graph); |
293 | 292 | ||
294 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | 293 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); |
295 | let module_id = module.def_id.loc(&db).module_id; | 294 | let krate = module.krate(&db).unwrap(); |
296 | let item_map = db.item_map(source_root); | 295 | let item_map = db.item_map(krate.crate_id); |
297 | 296 | ||
298 | check_module_item_map( | 297 | check_module_item_map( |
299 | &item_map, | 298 | &item_map, |
300 | module_id, | 299 | module.module_id, |
301 | " | 300 | " |
302 | C: t v | 301 | C: t v |
303 | test_crate: t | 302 | test_crate: t |
@@ -333,14 +332,13 @@ fn reexport_across_crates() { | |||
333 | 332 | ||
334 | db.set_crate_graph(crate_graph); | 333 | db.set_crate_graph(crate_graph); |
335 | 334 | ||
336 | let source_root = db.file_source_root(main_id); | ||
337 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); | 335 | let module = crate::source_binder::module_from_file_id(&db, main_id).unwrap(); |
338 | let module_id = module.def_id.loc(&db).module_id; | 336 | let krate = module.krate(&db).unwrap(); |
339 | let item_map = db.item_map(source_root); | 337 | let item_map = db.item_map(krate.crate_id); |
340 | 338 | ||
341 | check_module_item_map( | 339 | check_module_item_map( |
342 | &item_map, | 340 | &item_map, |
343 | module_id, | 341 | module.module_id, |
344 | " | 342 | " |
345 | Baz: t v | 343 | Baz: t v |
346 | test_crate: t | 344 | test_crate: t |
@@ -350,10 +348,11 @@ fn reexport_across_crates() { | |||
350 | 348 | ||
351 | fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { | 349 | fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { |
352 | let (mut db, pos) = MockDatabase::with_position(initial); | 350 | let (mut db, pos) = MockDatabase::with_position(initial); |
353 | let source_root = db.file_source_root(pos.file_id); | 351 | let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap(); |
352 | let krate = module.krate(&db).unwrap(); | ||
354 | { | 353 | { |
355 | let events = db.log_executed(|| { | 354 | let events = db.log_executed(|| { |
356 | db.item_map(source_root); | 355 | db.item_map(krate.crate_id); |
357 | }); | 356 | }); |
358 | assert!(format!("{:?}", events).contains("item_map")) | 357 | assert!(format!("{:?}", events).contains("item_map")) |
359 | } | 358 | } |
@@ -362,7 +361,7 @@ fn check_item_map_is_not_recomputed(initial: &str, file_change: &str) { | |||
362 | 361 | ||
363 | { | 362 | { |
364 | let events = db.log_executed(|| { | 363 | let events = db.log_executed(|| { |
365 | db.item_map(source_root); | 364 | db.item_map(krate.crate_id); |
366 | }); | 365 | }); |
367 | assert!( | 366 | assert!( |
368 | !format!("{:?}", events).contains("item_map"), | 367 | !format!("{:?}", events).contains("item_map"), |
diff --git a/crates/ra_hir/src/query_definitions.rs b/crates/ra_hir/src/query_definitions.rs index 074153862..a8ed887b3 100644 --- a/crates/ra_hir/src/query_definitions.rs +++ b/crates/ra_hir/src/query_definitions.rs | |||
@@ -7,11 +7,11 @@ use rustc_hash::FxHashMap; | |||
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | AstNode, SyntaxNode, TreeArc, | 8 | AstNode, SyntaxNode, TreeArc, |
9 | }; | 9 | }; |
10 | use ra_db::SourceRootId; | 10 | use ra_db::{CrateId}; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | SourceFileItems, SourceItemId, DefId, HirFileId, | 13 | SourceFileItems, SourceItemId, DefId, HirFileId, |
14 | FnScopes, | 14 | FnScopes, Module, |
15 | db::HirDatabase, | 15 | db::HirDatabase, |
16 | nameres::{ItemMap, Resolver}, | 16 | nameres::{ItemMap, Resolver}, |
17 | }; | 17 | }; |
@@ -41,15 +41,23 @@ pub(super) fn file_item( | |||
41 | } | 41 | } |
42 | } | 42 | } |
43 | 43 | ||
44 | pub(super) fn item_map(db: &impl HirDatabase, source_root: SourceRootId) -> Arc<ItemMap> { | 44 | pub(super) fn item_map(db: &impl HirDatabase, crate_id: CrateId) -> Arc<ItemMap> { |
45 | let start = Instant::now(); | 45 | let start = Instant::now(); |
46 | let module_tree = db.module_tree(source_root); | 46 | let module_tree = db.module_tree(crate_id); |
47 | let input = module_tree | 47 | let input = module_tree |
48 | .modules() | 48 | .modules() |
49 | .map(|id| (id, db.lower_module_module(source_root, id))) | 49 | .map(|module_id| { |
50 | ( | ||
51 | module_id, | ||
52 | db.lower_module_module(Module { | ||
53 | krate: crate_id, | ||
54 | module_id, | ||
55 | }), | ||
56 | ) | ||
57 | }) | ||
50 | .collect::<FxHashMap<_, _>>(); | 58 | .collect::<FxHashMap<_, _>>(); |
51 | 59 | ||
52 | let resolver = Resolver::new(db, &input, source_root, module_tree); | 60 | let resolver = Resolver::new(db, &input, crate_id); |
53 | let res = resolver.resolve(); | 61 | let res = resolver.resolve(); |
54 | let elapsed = start.elapsed(); | 62 | let elapsed = start.elapsed(); |
55 | log::info!("item_map: {:?}", elapsed); | 63 | log::info!("item_map: {:?}", elapsed); |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index bde0be37b..c3bd31d6b 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -13,7 +13,7 @@ use ra_syntax::{ | |||
13 | }; | 13 | }; |
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | HirDatabase, Function, SourceItemId, | 16 | HirDatabase, Function, SourceItemId, ModuleDef, |
17 | DefKind, DefLoc, AsName, Module, | 17 | DefKind, DefLoc, AsName, Module, |
18 | }; | 18 | }; |
19 | 19 | ||
@@ -84,9 +84,13 @@ pub fn module_from_child_node( | |||
84 | 84 | ||
85 | fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Option<Module> { | 85 | fn module_from_source(db: &impl HirDatabase, source: SourceItemId) -> Option<Module> { |
86 | let source_root_id = db.file_source_root(source.file_id.as_original_file()); | 86 | let source_root_id = db.file_source_root(source.file_id.as_original_file()); |
87 | let module_tree = db.module_tree(source_root_id); | 87 | db.source_root_crates(source_root_id) |
88 | let module_id = module_tree.find_module_by_source(source)?; | 88 | .iter() |
89 | Some(Module::from_module_id(db, source_root_id, module_id)) | 89 | .find_map(|&krate| { |
90 | let module_tree = db.module_tree(krate); | ||
91 | let module_id = module_tree.find_module_by_source(source)?; | ||
92 | Some(Module { krate, module_id }) | ||
93 | }) | ||
90 | } | 94 | } |
91 | 95 | ||
92 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { | 96 | pub fn function_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Function> { |
@@ -110,8 +114,8 @@ pub fn function_from_module( | |||
110 | module: &Module, | 114 | module: &Module, |
111 | fn_def: &ast::FnDef, | 115 | fn_def: &ast::FnDef, |
112 | ) -> Function { | 116 | ) -> Function { |
113 | let loc = module.def_id.loc(db); | 117 | let (file_id, _) = module.definition_source(db); |
114 | let file_id = loc.source_item_id.file_id; | 118 | let file_id = file_id.into(); |
115 | let file_items = db.file_items(file_id); | 119 | let file_items = db.file_items(file_id); |
116 | let item_id = file_items.id_of(file_id, fn_def.syntax()); | 120 | let item_id = file_items.id_of(file_id, fn_def.syntax()); |
117 | let source_item_id = SourceItemId { | 121 | let source_item_id = SourceItemId { |
@@ -119,9 +123,8 @@ pub fn function_from_module( | |||
119 | item_id: Some(item_id), | 123 | item_id: Some(item_id), |
120 | }; | 124 | }; |
121 | let def_loc = DefLoc { | 125 | let def_loc = DefLoc { |
126 | module: module.clone(), | ||
122 | kind: DefKind::Function, | 127 | kind: DefKind::Function, |
123 | source_root_id: loc.source_root_id, | ||
124 | module_id: loc.module_id, | ||
125 | source_item_id, | 128 | source_item_id, |
126 | }; | 129 | }; |
127 | Function::new(def_loc.id(db)) | 130 | Function::new(def_loc.id(db)) |
@@ -141,14 +144,17 @@ pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, Te | |||
141 | Some(it) => it, | 144 | Some(it) => it, |
142 | None => return Vec::new(), | 145 | None => return Vec::new(), |
143 | }; | 146 | }; |
144 | let loc = module.def_id.loc(db); | 147 | let items = db.lower_module_module(module); |
145 | let items = db.lower_module_module(loc.source_root_id, loc.module_id); | ||
146 | let mut res = Vec::new(); | 148 | let mut res = Vec::new(); |
147 | 149 | ||
148 | for macro_call_id in items | 150 | for macro_call_id in items |
149 | .declarations | 151 | .declarations |
150 | .iter() | 152 | .iter() |
151 | .filter_map(|(_, it)| it.take_types()) | 153 | .filter_map(|(_, it)| it.clone().take_types()) |
154 | .filter_map(|it| match it { | ||
155 | ModuleDef::Def(it) => Some(it), | ||
156 | _ => None, | ||
157 | }) | ||
152 | .filter_map(|it| it.loc(db).source_item_id.file_id.as_macro_call_id()) | 158 | .filter_map(|it| it.loc(db).source_item_id.file_id.as_macro_call_id()) |
153 | { | 159 | { |
154 | if let Some(exp) = db.expand_macro_invocation(macro_call_id) { | 160 | if let Some(exp) = db.expand_macro_invocation(macro_call_id) { |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index e690ae158..4c96579ee 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -32,7 +32,7 @@ use rustc_hash::FxHashMap; | |||
32 | 32 | ||
33 | use crate::{ | 33 | use crate::{ |
34 | Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, | 34 | Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, |
35 | FnSignature, FnScopes, | 35 | FnSignature, FnScopes, ModuleDef, |
36 | db::HirDatabase, | 36 | db::HirDatabase, |
37 | type_ref::{TypeRef, Mutability}, | 37 | type_ref::{TypeRef, Mutability}, |
38 | name::KnownName, | 38 | name::KnownName, |
@@ -382,8 +382,8 @@ impl Ty { | |||
382 | 382 | ||
383 | // Resolve in module (in type namespace) | 383 | // Resolve in module (in type namespace) |
384 | let resolved = match module.resolve_path(db, path).take_types() { | 384 | let resolved = match module.resolve_path(db, path).take_types() { |
385 | Some(r) => r, | 385 | Some(ModuleDef::Def(r)) => r, |
386 | None => return Ty::Unknown, | 386 | None | Some(ModuleDef::Module(_)) => return Ty::Unknown, |
387 | }; | 387 | }; |
388 | let ty = db.type_for_def(resolved); | 388 | let ty = db.type_for_def(resolved); |
389 | let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved); | 389 | let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved); |
@@ -663,10 +663,6 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T | |||
663 | pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty { | 663 | pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty { |
664 | let def = def_id.resolve(db); | 664 | let def = def_id.resolve(db); |
665 | match def { | 665 | match def { |
666 | Def::Module(..) => { | ||
667 | log::debug!("trying to get type for module {:?}", def_id); | ||
668 | Ty::Unknown | ||
669 | } | ||
670 | Def::Function(f) => type_for_fn(db, f), | 666 | Def::Function(f) => type_for_fn(db, f), |
671 | Def::Struct(s) => type_for_struct(db, s), | 667 | Def::Struct(s) => type_for_struct(db, s), |
672 | Def::Enum(e) => type_for_enum(db, e), | 668 | Def::Enum(e) => type_for_enum(db, e), |
@@ -1063,7 +1059,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1063 | }; | 1059 | }; |
1064 | 1060 | ||
1065 | // resolve in module | 1061 | // resolve in module |
1066 | let resolved = self.module.resolve_path(self.db, &path).take_values()?; | 1062 | let resolved = match self.module.resolve_path(self.db, &path).take_values()? { |
1063 | ModuleDef::Def(it) => it, | ||
1064 | ModuleDef::Module(_) => return None, | ||
1065 | }; | ||
1067 | let ty = self.db.type_for_def(resolved); | 1066 | let ty = self.db.type_for_def(resolved); |
1068 | let ty = self.insert_type_vars(ty); | 1067 | let ty = self.insert_type_vars(ty); |
1069 | Some(ty) | 1068 | Some(ty) |
@@ -1075,7 +1074,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1075 | None => return (Ty::Unknown, None), | 1074 | None => return (Ty::Unknown, None), |
1076 | }; | 1075 | }; |
1077 | let def_id = match self.module.resolve_path(self.db, &path).take_types() { | 1076 | let def_id = match self.module.resolve_path(self.db, &path).take_types() { |
1078 | Some(def_id) => def_id, | 1077 | Some(ModuleDef::Def(def_id)) => def_id, |
1079 | _ => return (Ty::Unknown, None), | 1078 | _ => return (Ty::Unknown, None), |
1080 | }; | 1079 | }; |
1081 | // TODO remove the duplication between here and `Ty::from_path`? | 1080 | // TODO remove the duplication between here and `Ty::from_path`? |
@@ -1216,6 +1215,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1216 | .module | 1215 | .module |
1217 | .resolve_path(self.db, &path) | 1216 | .resolve_path(self.db, &path) |
1218 | .take_values() | 1217 | .take_values() |
1218 | .and_then(|module_def| match module_def { | ||
1219 | ModuleDef::Def(it) => Some(it), | ||
1220 | ModuleDef::Module(_) => None, | ||
1221 | }) | ||
1219 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), | 1222 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), |
1220 | Pat::Bind { | 1223 | Pat::Bind { |
1221 | mode, | 1224 | mode, |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 9f65c5fe1..a5567a78f 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -6,8 +6,6 @@ use std::sync::Arc; | |||
6 | 6 | ||
7 | use rustc_hash::FxHashMap; | 7 | use rustc_hash::FxHashMap; |
8 | 8 | ||
9 | use ra_db::SourceRootId; | ||
10 | |||
11 | use crate::{ | 9 | use crate::{ |
12 | HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, | 10 | HirDatabase, DefId, module_tree::ModuleId, Module, Crate, Name, Function, |
13 | impl_block::{ImplId, ImplBlock, ImplItem}, | 11 | impl_block::{ImplId, ImplBlock, ImplItem}, |
@@ -37,7 +35,7 @@ impl TyFingerprint { | |||
37 | #[derive(Debug, PartialEq, Eq)] | 35 | #[derive(Debug, PartialEq, Eq)] |
38 | pub struct CrateImplBlocks { | 36 | pub struct CrateImplBlocks { |
39 | /// To make sense of the ModuleIds, we need the source root. | 37 | /// To make sense of the ModuleIds, we need the source root. |
40 | source_root_id: SourceRootId, | 38 | krate: Crate, |
41 | impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>, | 39 | impls: FxHashMap<TyFingerprint, Vec<(ModuleId, ImplId)>>, |
42 | } | 40 | } |
43 | 41 | ||
@@ -53,14 +51,17 @@ impl CrateImplBlocks { | |||
53 | .into_iter() | 51 | .into_iter() |
54 | .flat_map(|i| i.iter()) | 52 | .flat_map(|i| i.iter()) |
55 | .map(move |(module_id, impl_id)| { | 53 | .map(move |(module_id, impl_id)| { |
56 | let module_impl_blocks = db.impls_in_module(self.source_root_id, *module_id); | 54 | let module = Module { |
55 | krate: self.krate.crate_id, | ||
56 | module_id: *module_id, | ||
57 | }; | ||
58 | let module_impl_blocks = db.impls_in_module(module); | ||
57 | ImplBlock::from_id(module_impl_blocks, *impl_id) | 59 | ImplBlock::from_id(module_impl_blocks, *impl_id) |
58 | }) | 60 | }) |
59 | } | 61 | } |
60 | 62 | ||
61 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { | 63 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: &Module) { |
62 | let module_id = module.def_id.loc(db).module_id; | 64 | let module_impl_blocks = db.impls_in_module(module.clone()); |
63 | let module_impl_blocks = db.impls_in_module(self.source_root_id, module_id); | ||
64 | 65 | ||
65 | for (impl_id, impl_data) in module_impl_blocks.impls.iter() { | 66 | for (impl_id, impl_data) in module_impl_blocks.impls.iter() { |
66 | let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id); | 67 | let impl_block = ImplBlock::from_id(Arc::clone(&module_impl_blocks), impl_id); |
@@ -81,13 +82,13 @@ impl CrateImplBlocks { | |||
81 | self.impls | 82 | self.impls |
82 | .entry(target_ty_fp) | 83 | .entry(target_ty_fp) |
83 | .or_insert_with(Vec::new) | 84 | .or_insert_with(Vec::new) |
84 | .push((module_id, impl_id)); | 85 | .push((module.module_id, impl_id)); |
85 | } | 86 | } |
86 | } | 87 | } |
87 | } | 88 | } |
88 | 89 | ||
89 | for child in module.children(db) { | 90 | for child in module.children(db) { |
90 | self.collect_recursive(db, child); | 91 | self.collect_recursive(db, &child); |
91 | } | 92 | } |
92 | } | 93 | } |
93 | 94 | ||
@@ -95,15 +96,12 @@ impl CrateImplBlocks { | |||
95 | db: &impl HirDatabase, | 96 | db: &impl HirDatabase, |
96 | krate: Crate, | 97 | krate: Crate, |
97 | ) -> Arc<CrateImplBlocks> { | 98 | ) -> Arc<CrateImplBlocks> { |
98 | let crate_graph = db.crate_graph(); | ||
99 | let file_id = crate_graph.crate_root(krate.crate_id); | ||
100 | let source_root_id = db.file_source_root(file_id); | ||
101 | let mut crate_impl_blocks = CrateImplBlocks { | 99 | let mut crate_impl_blocks = CrateImplBlocks { |
102 | source_root_id, | 100 | krate: krate.clone(), |
103 | impls: FxHashMap::default(), | 101 | impls: FxHashMap::default(), |
104 | }; | 102 | }; |
105 | if let Some(module) = krate.root_module(db) { | 103 | if let Some(module) = krate.root_module(db) { |
106 | crate_impl_blocks.collect_recursive(db, module); | 104 | crate_impl_blocks.collect_recursive(db, &module); |
107 | } | 105 | } |
108 | Arc::new(crate_impl_blocks) | 106 | Arc::new(crate_impl_blocks) |
109 | } | 107 | } |
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index e44b76c4a..0d7942496 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -13,8 +13,8 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
13 | Some(it) => it, | 13 | Some(it) => it, |
14 | None => return, | 14 | None => return, |
15 | }; | 15 | }; |
16 | match def_id.resolve(ctx.db) { | 16 | match def_id { |
17 | hir::Def::Module(module) => { | 17 | hir::ModuleDef::Module(module) => { |
18 | let module_scope = module.scope(ctx.db); | 18 | let module_scope = module.scope(ctx.db); |
19 | for (name, res) in module_scope.entries() { | 19 | for (name, res) in module_scope.entries() { |
20 | CompletionItem::new( | 20 | CompletionItem::new( |
@@ -26,21 +26,24 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
26 | .add_to(acc); | 26 | .add_to(acc); |
27 | } | 27 | } |
28 | } | 28 | } |
29 | hir::Def::Enum(e) => { | 29 | |
30 | e.variants(ctx.db) | 30 | hir::ModuleDef::Def(def_id) => match def_id.resolve(ctx.db) { |
31 | .into_iter() | 31 | hir::Def::Enum(e) => { |
32 | .for_each(|(variant_name, variant)| { | 32 | e.variants(ctx.db) |
33 | CompletionItem::new( | 33 | .into_iter() |
34 | CompletionKind::Reference, | 34 | .for_each(|(variant_name, variant)| { |
35 | ctx.source_range(), | 35 | CompletionItem::new( |
36 | variant_name.to_string(), | 36 | CompletionKind::Reference, |
37 | ) | 37 | ctx.source_range(), |
38 | .kind(CompletionItemKind::EnumVariant) | 38 | variant_name.to_string(), |
39 | .set_documentation(variant.docs(ctx.db)) | 39 | ) |
40 | .add_to(acc) | 40 | .kind(CompletionItemKind::EnumVariant) |
41 | }); | 41 | .set_documentation(variant.docs(ctx.db)) |
42 | } | 42 | .add_to(acc) |
43 | _ => return, | 43 | }); |
44 | } | ||
45 | _ => return, | ||
46 | }, | ||
44 | }; | 47 | }; |
45 | } | 48 | } |
46 | 49 | ||
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index 18c151932..5d6718a8d 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs | |||
@@ -1,6 +1,4 @@ | |||
1 | use hir::{Docs, Documentation, PerNs}; | 1 | use hir::{Docs, Documentation}; |
2 | |||
3 | use crate::completion::completion_context::CompletionContext; | ||
4 | use ra_syntax::{ | 2 | use ra_syntax::{ |
5 | ast::{self, AstNode}, | 3 | ast::{self, AstNode}, |
6 | TextRange, | 4 | TextRange, |
@@ -8,6 +6,8 @@ use ra_syntax::{ | |||
8 | use ra_text_edit::TextEdit; | 6 | use ra_text_edit::TextEdit; |
9 | use test_utils::tested_by; | 7 | use test_utils::tested_by; |
10 | 8 | ||
9 | use crate::completion::completion_context::CompletionContext; | ||
10 | |||
11 | /// `CompletionItem` describes a single completion variant in the editor pop-up. | 11 | /// `CompletionItem` describes a single completion variant in the editor pop-up. |
12 | /// It is basically a POD with various properties. To construct a | 12 | /// It is basically a POD with various properties. To construct a |
13 | /// `CompletionItem`, use `new` method and the `Builder` struct. | 13 | /// `CompletionItem`, use `new` method and the `Builder` struct. |
@@ -209,41 +209,26 @@ impl Builder { | |||
209 | ctx: &CompletionContext, | 209 | ctx: &CompletionContext, |
210 | resolution: &hir::Resolution, | 210 | resolution: &hir::Resolution, |
211 | ) -> Builder { | 211 | ) -> Builder { |
212 | let resolved = resolution.def_id.map(|d| d.resolve(ctx.db)); | 212 | let def = resolution |
213 | let (kind, docs) = match resolved { | 213 | .def_id |
214 | PerNs { | 214 | .take_types() |
215 | types: Some(hir::Def::Module(..)), | 215 | .or(resolution.def_id.take_values()); |
216 | .. | 216 | let def = match def { |
217 | } => (CompletionItemKind::Module, None), | 217 | None => return self, |
218 | PerNs { | 218 | Some(it) => it, |
219 | types: Some(hir::Def::Struct(s)), | 219 | }; |
220 | .. | 220 | let (kind, docs) = match def { |
221 | } => (CompletionItemKind::Struct, s.docs(ctx.db)), | 221 | hir::ModuleDef::Module(_) => (CompletionItemKind::Module, None), |
222 | PerNs { | 222 | hir::ModuleDef::Def(def_id) => match def_id.resolve(ctx.db) { |
223 | types: Some(hir::Def::Enum(e)), | 223 | hir::Def::Struct(it) => (CompletionItemKind::Struct, it.docs(ctx.db)), |
224 | .. | 224 | hir::Def::Enum(it) => (CompletionItemKind::Enum, it.docs(ctx.db)), |
225 | } => (CompletionItemKind::Enum, e.docs(ctx.db)), | 225 | hir::Def::Trait(it) => (CompletionItemKind::Trait, it.docs(ctx.db)), |
226 | PerNs { | 226 | hir::Def::Type(it) => (CompletionItemKind::TypeAlias, it.docs(ctx.db)), |
227 | types: Some(hir::Def::Trait(t)), | 227 | hir::Def::Const(it) => (CompletionItemKind::Const, it.docs(ctx.db)), |
228 | .. | 228 | hir::Def::Static(it) => (CompletionItemKind::Static, it.docs(ctx.db)), |
229 | } => (CompletionItemKind::Trait, t.docs(ctx.db)), | 229 | hir::Def::Function(function) => return self.from_function(ctx, function), |
230 | PerNs { | 230 | _ => return self, |
231 | types: Some(hir::Def::Type(t)), | 231 | }, |
232 | .. | ||
233 | } => (CompletionItemKind::TypeAlias, t.docs(ctx.db)), | ||
234 | PerNs { | ||
235 | values: Some(hir::Def::Const(c)), | ||
236 | .. | ||
237 | } => (CompletionItemKind::Const, c.docs(ctx.db)), | ||
238 | PerNs { | ||
239 | values: Some(hir::Def::Static(s)), | ||
240 | .. | ||
241 | } => (CompletionItemKind::Static, s.docs(ctx.db)), | ||
242 | PerNs { | ||
243 | values: Some(hir::Def::Function(function)), | ||
244 | .. | ||
245 | } => return self.from_function(ctx, function), | ||
246 | _ => return self, | ||
247 | }; | 232 | }; |
248 | self.kind = Some(kind); | 233 | self.kind = Some(kind); |
249 | self.documentation = docs; | 234 | self.documentation = docs; |
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index ba0eb1cb8..bff6b7237 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -72,6 +72,7 @@ salsa::database_storage! { | |||
72 | fn file_relative_path() for ra_db::FileRelativePathQuery; | 72 | fn file_relative_path() for ra_db::FileRelativePathQuery; |
73 | fn file_source_root() for ra_db::FileSourceRootQuery; | 73 | fn file_source_root() for ra_db::FileSourceRootQuery; |
74 | fn source_root() for ra_db::SourceRootQuery; | 74 | fn source_root() for ra_db::SourceRootQuery; |
75 | fn source_root_crates() for ra_db::SourceRootCratesQuery; | ||
75 | fn local_roots() for ra_db::LocalRootsQuery; | 76 | fn local_roots() for ra_db::LocalRootsQuery; |
76 | fn library_roots() for ra_db::LibraryRootsQuery; | 77 | fn library_roots() for ra_db::LibraryRootsQuery; |
77 | fn crate_graph() for ra_db::CrateGraphQuery; | 78 | fn crate_graph() for ra_db::CrateGraphQuery; |
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index b1becca03..323bb1cc1 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -67,7 +67,7 @@ pub(crate) fn reference_definition( | |||
67 | .node_expr(expr) | 67 | .node_expr(expr) |
68 | .and_then(|it| infer_result.method_resolution(it)) | 68 | .and_then(|it| infer_result.method_resolution(it)) |
69 | { | 69 | { |
70 | if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)) { | 70 | if let Some(target) = NavigationTarget::from_def(db, hir::ModuleDef::Def(def_id)) { |
71 | return Exact(target); | 71 | return Exact(target); |
72 | } | 72 | } |
73 | }; | 73 | }; |
@@ -84,7 +84,7 @@ pub(crate) fn reference_definition( | |||
84 | { | 84 | { |
85 | let resolved = module.resolve_path(db, &path); | 85 | let resolved = module.resolve_path(db, &path); |
86 | if let Some(def_id) = resolved.take_types().or(resolved.take_values()) { | 86 | if let Some(def_id) = resolved.take_types().or(resolved.take_values()) { |
87 | if let Some(target) = NavigationTarget::from_def(db, def_id.resolve(db)) { | 87 | if let Some(target) = NavigationTarget::from_def(db, def_id) { |
88 | return Exact(target); | 88 | return Exact(target); |
89 | } | 89 | } |
90 | } | 90 | } |
diff --git a/crates/ra_ide_api/src/navigation_target.rs b/crates/ra_ide_api/src/navigation_target.rs index 21c15c0c0..1eb177665 100644 --- a/crates/ra_ide_api/src/navigation_target.rs +++ b/crates/ra_ide_api/src/navigation_target.rs | |||
@@ -97,7 +97,17 @@ impl NavigationTarget { | |||
97 | } | 97 | } |
98 | 98 | ||
99 | // TODO once Def::Item is gone, this should be able to always return a NavigationTarget | 99 | // TODO once Def::Item is gone, this should be able to always return a NavigationTarget |
100 | pub(crate) fn from_def(db: &RootDatabase, def: Def) -> Option<NavigationTarget> { | 100 | pub(crate) fn from_def( |
101 | db: &RootDatabase, | ||
102 | module_def: hir::ModuleDef, | ||
103 | ) -> Option<NavigationTarget> { | ||
104 | let def = match module_def { | ||
105 | hir::ModuleDef::Def(def_id) => def_id.resolve(db), | ||
106 | hir::ModuleDef::Module(module) => { | ||
107 | return Some(NavigationTarget::from_module(db, module)); | ||
108 | } | ||
109 | }; | ||
110 | |||
101 | let res = match def { | 111 | let res = match def { |
102 | Def::Struct(s) => { | 112 | Def::Struct(s) => { |
103 | let (file_id, node) = s.source(db); | 113 | let (file_id, node) = s.source(db); |
@@ -131,7 +141,6 @@ impl NavigationTarget { | |||
131 | let (file_id, node) = f.source(db); | 141 | let (file_id, node) = f.source(db); |
132 | NavigationTarget::from_named(file_id.original_file(db), &*node) | 142 | NavigationTarget::from_named(file_id.original_file(db), &*node) |
133 | } | 143 | } |
134 | Def::Module(m) => NavigationTarget::from_module(db, m), | ||
135 | Def::Item => return None, | 144 | Def::Item => return None, |
136 | }; | 145 | }; |
137 | Some(res) | 146 | Some(res) |
diff --git a/crates/ra_ide_api/src/rename.rs b/crates/ra_ide_api/src/rename.rs index 53dc273c6..5b767addd 100644 --- a/crates/ra_ide_api/src/rename.rs +++ b/crates/ra_ide_api/src/rename.rs | |||
@@ -57,7 +57,6 @@ fn rename_mod( | |||
57 | ) -> Option<SourceChange> { | 57 | ) -> Option<SourceChange> { |
58 | let mut source_file_edits = Vec::new(); | 58 | let mut source_file_edits = Vec::new(); |
59 | let mut file_system_edits = Vec::new(); | 59 | let mut file_system_edits = Vec::new(); |
60 | |||
61 | if let Some(module) = module_from_declaration(db, position.file_id, &ast_module) { | 60 | if let Some(module) = module_from_declaration(db, position.file_id, &ast_module) { |
62 | let (file_id, module_source) = module.definition_source(db); | 61 | let (file_id, module_source) = module.definition_source(db); |
63 | match module_source { | 62 | match module_source { |
@@ -223,11 +222,15 @@ mod tests { | |||
223 | fn test_rename_mod() { | 222 | fn test_rename_mod() { |
224 | let (analysis, position) = analysis_and_position( | 223 | let (analysis, position) = analysis_and_position( |
225 | " | 224 | " |
226 | //- /bar.rs | 225 | //- /lib.rs |
227 | mod fo<|>o; | 226 | mod bar; |
228 | //- /bar/foo.rs | 227 | |
229 | // emtpy | 228 | //- /bar.rs |
230 | ", | 229 | mod foo<|>; |
230 | |||
231 | //- /bar/foo.rs | ||
232 | // emtpy | ||
233 | ", | ||
231 | ); | 234 | ); |
232 | let new_name = "foo2"; | 235 | let new_name = "foo2"; |
233 | let source_change = analysis.rename(position, new_name).unwrap(); | 236 | let source_change = analysis.rename(position, new_name).unwrap(); |
@@ -238,11 +241,11 @@ mod tests { | |||
238 | fn test_rename_mod_in_dir() { | 241 | fn test_rename_mod_in_dir() { |
239 | let (analysis, position) = analysis_and_position( | 242 | let (analysis, position) = analysis_and_position( |
240 | " | 243 | " |
241 | //- /lib.rs | 244 | //- /lib.rs |
242 | mod fo<|>o; | 245 | mod fo<|>o; |
243 | //- /foo/mod.rs | 246 | //- /foo/mod.rs |
244 | // emtpy | 247 | // emtpy |
245 | ", | 248 | ", |
246 | ); | 249 | ); |
247 | let new_name = "foo2"; | 250 | let new_name = "foo2"; |
248 | let source_change = analysis.rename(position, new_name).unwrap(); | 251 | let source_change = analysis.rename(position, new_name).unwrap(); |
diff --git a/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap b/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap index 3267d1ac5..890426db7 100644 --- a/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap +++ b/crates/ra_ide_api/src/snapshots/tests__rename_mod.snap | |||
@@ -1,8 +1,8 @@ | |||
1 | --- | 1 | --- |
2 | created: "2019-01-22T14:45:00.975229300+00:00" | 2 | created: "2019-01-24T08:39:53.759318522+00:00" |
3 | creator: insta@0.4.0 | 3 | creator: insta@0.5.2 |
4 | expression: "&source_change" | 4 | expression: "&source_change" |
5 | source: "crates\\ra_ide_api\\src\\rename.rs" | 5 | source: crates/ra_ide_api/src/rename.rs |
6 | --- | 6 | --- |
7 | Some( | 7 | Some( |
8 | SourceChange { | 8 | SourceChange { |
@@ -10,7 +10,7 @@ Some( | |||
10 | source_file_edits: [ | 10 | source_file_edits: [ |
11 | SourceFileEdit { | 11 | SourceFileEdit { |
12 | file_id: FileId( | 12 | file_id: FileId( |
13 | 1 | 13 | 2 |
14 | ), | 14 | ), |
15 | edit: TextEdit { | 15 | edit: TextEdit { |
16 | atoms: [ | 16 | atoms: [ |
@@ -25,7 +25,7 @@ Some( | |||
25 | file_system_edits: [ | 25 | file_system_edits: [ |
26 | MoveFile { | 26 | MoveFile { |
27 | src: FileId( | 27 | src: FileId( |
28 | 2 | 28 | 3 |
29 | ), | 29 | ), |
30 | dst_source_root: SourceRootId( | 30 | dst_source_root: SourceRootId( |
31 | 0 | 31 | 0 |