diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/has_source.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/db.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_scope.rs | 35 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 46 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 68 | ||||
-rw-r--r-- | crates/ra_hir_def/src/trace.rs | 8 | ||||
-rw-r--r-- | crates/ra_ide/src/change.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/complete_path.rs | 17 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/completion_context.rs | 4 |
13 files changed, 166 insertions, 71 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index e6768ea0b..fca3a2950 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -12,8 +12,8 @@ use hir_def::{ | |||
12 | resolver::HasResolver, | 12 | resolver::HasResolver, |
13 | type_ref::{Mutability, TypeRef}, | 13 | type_ref::{Mutability, TypeRef}, |
14 | AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, | 14 | AdtId, ConstId, DefWithBodyId, EnumId, FunctionId, HasModule, ImplId, LocalEnumVariantId, |
15 | LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, | 15 | LocalImportId, LocalModuleId, LocalStructFieldId, Lookup, ModuleId, StaticId, StructId, |
16 | TypeParamId, UnionId, | 16 | TraitId, TypeAliasId, TypeParamId, UnionId, |
17 | }; | 17 | }; |
18 | use hir_expand::{ | 18 | use hir_expand::{ |
19 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
@@ -180,11 +180,13 @@ impl Module { | |||
180 | } | 180 | } |
181 | 181 | ||
182 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 182 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
183 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef)> { | 183 | pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> { |
184 | db.crate_def_map(self.id.krate)[self.id.local_id] | 184 | db.crate_def_map(self.id.krate)[self.id.local_id] |
185 | .scope | 185 | .scope |
186 | .entries() | 186 | .entries() |
187 | .map(|(name, res)| (name.clone(), res.def.into())) | 187 | .map(|(name, res)| { |
188 | (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id })) | ||
189 | }) | ||
188 | .collect() | 190 | .collect() |
189 | } | 191 | } |
190 | 192 | ||
@@ -227,10 +229,10 @@ impl Module { | |||
227 | } | 229 | } |
228 | } | 230 | } |
229 | 231 | ||
230 | // pub struct Import { | 232 | pub struct Import { |
231 | // pub(crate) parent: Module, | 233 | pub(crate) parent: Module, |
232 | // pub(crate) id: LocalImportId, | 234 | pub(crate) id: LocalImportId, |
233 | // } | 235 | } |
234 | 236 | ||
235 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 237 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
236 | pub struct StructField { | 238 | pub struct StructField { |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index f5ffd64fa..bfae3660b 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -4,8 +4,8 @@ pub use hir_def::db::{ | |||
4 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, | 4 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, |
5 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, | 5 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, |
6 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, | 6 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, |
7 | LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, StaticDataQuery, StructDataQuery, | 7 | LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery, |
8 | TraitDataQuery, TypeAliasDataQuery, | 8 | StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, |
9 | }; | 9 | }; |
10 | pub use hir_expand::db::{ | 10 | pub use hir_expand::db::{ |
11 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 11 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
diff --git a/crates/ra_hir/src/has_source.rs b/crates/ra_hir/src/has_source.rs index 5541266e2..72afecf26 100644 --- a/crates/ra_hir/src/has_source.rs +++ b/crates/ra_hir/src/has_source.rs | |||
@@ -9,8 +9,8 @@ use hir_def::{ | |||
9 | use ra_syntax::ast; | 9 | use ra_syntax::ast; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, MacroDef, Module, | 12 | db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef, |
13 | Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, | 13 | Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | pub use hir_expand::InFile; | 16 | pub use hir_expand::InFile; |
@@ -117,6 +117,18 @@ impl HasSource for ImplBlock { | |||
117 | self.id.lookup(db).source(db) | 117 | self.id.lookup(db).source(db) |
118 | } | 118 | } |
119 | } | 119 | } |
120 | impl HasSource for Import { | ||
121 | type Ast = Either<ast::UseTree, ast::ExternCrateItem>; | ||
122 | |||
123 | /// Returns the syntax of the last path segment corresponding to this import | ||
124 | fn source(self, db: &impl DefDatabase) -> InFile<Self::Ast> { | ||
125 | let src = self.parent.definition_source(db); | ||
126 | let (_, source_map) = db.raw_items_with_source_map(src.file_id); | ||
127 | let root = db.parse_or_expand(src.file_id).unwrap(); | ||
128 | let ptr = source_map.get(self.id); | ||
129 | src.with_value(ptr.map_left(|it| it.to_node(&root)).map_right(|it| it.to_node(&root))) | ||
130 | } | ||
131 | } | ||
120 | 132 | ||
121 | impl HasSource for TypeParam { | 133 | impl HasSource for TypeParam { |
122 | type Ast = Either<ast::TraitDef, ast::TypeParam>; | 134 | type Ast = Either<ast::TraitDef, ast::TypeParam>; |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 0008a8858..7f9aef770 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -40,8 +40,8 @@ mod from_source; | |||
40 | pub use crate::{ | 40 | pub use crate::{ |
41 | code_model::{ | 41 | code_model::{ |
42 | Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, | 42 | Adt, AssocItem, AttrDef, Const, Crate, CrateDependency, DefWithBody, Docs, Enum, |
43 | EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Local, MacroDef, | 43 | EnumVariant, FieldSource, Function, GenericDef, HasAttrs, ImplBlock, Import, Local, |
44 | Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, | 44 | MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, |
45 | TypeParam, Union, VariantDef, | 45 | TypeParam, Union, VariantDef, |
46 | }, | 46 | }, |
47 | from_source::FromSource, | 47 | from_source::FromSource, |
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index c55fd4111..98bff6cb7 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs | |||
@@ -13,7 +13,10 @@ use crate::{ | |||
13 | docs::Documentation, | 13 | docs::Documentation, |
14 | generics::GenericParams, | 14 | generics::GenericParams, |
15 | lang_item::{LangItemTarget, LangItems}, | 15 | lang_item::{LangItemTarget, LangItems}, |
16 | nameres::{raw::RawItems, CrateDefMap}, | 16 | nameres::{ |
17 | raw::{ImportSourceMap, RawItems}, | ||
18 | CrateDefMap, | ||
19 | }, | ||
17 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, | 20 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, |
18 | GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, | 21 | GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, |
19 | TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, | 22 | TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, |
@@ -43,6 +46,12 @@ pub trait InternDatabase: SourceDatabase { | |||
43 | 46 | ||
44 | #[salsa::query_group(DefDatabaseStorage)] | 47 | #[salsa::query_group(DefDatabaseStorage)] |
45 | pub trait DefDatabase: InternDatabase + AstDatabase { | 48 | pub trait DefDatabase: InternDatabase + AstDatabase { |
49 | #[salsa::invoke(RawItems::raw_items_with_source_map_query)] | ||
50 | fn raw_items_with_source_map( | ||
51 | &self, | ||
52 | file_id: HirFileId, | ||
53 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>); | ||
54 | |||
46 | #[salsa::invoke(RawItems::raw_items_query)] | 55 | #[salsa::invoke(RawItems::raw_items_query)] |
47 | fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; | 56 | fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; |
48 | 57 | ||
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 5c14fefff..6b9be8325 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs | |||
@@ -5,7 +5,7 @@ use hir_expand::name::Name; | |||
5 | use once_cell::sync::Lazy; | 5 | use once_cell::sync::Lazy; |
6 | use rustc_hash::FxHashMap; | 6 | use rustc_hash::FxHashMap; |
7 | 7 | ||
8 | use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId}; | 8 | use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId}; |
9 | 9 | ||
10 | #[derive(Debug, Default, PartialEq, Eq)] | 10 | #[derive(Debug, Default, PartialEq, Eq)] |
11 | pub struct ItemScope { | 11 | pub struct ItemScope { |
@@ -30,7 +30,7 @@ static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| { | |||
30 | BuiltinType::ALL | 30 | BuiltinType::ALL |
31 | .iter() | 31 | .iter() |
32 | .map(|(name, ty)| { | 32 | .map(|(name, ty)| { |
33 | (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), declaration: false }) | 33 | (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None }) |
34 | }) | 34 | }) |
35 | .collect() | 35 | .collect() |
36 | }); | 36 | }); |
@@ -53,9 +53,11 @@ impl ItemScope { | |||
53 | } | 53 | } |
54 | 54 | ||
55 | pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ { | 55 | pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ { |
56 | self.entries().filter(|(_name, res)| res.declaration).flat_map(|(_name, res)| { | 56 | self.entries() |
57 | res.def.take_types().into_iter().chain(res.def.take_values().into_iter()) | 57 | .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) |
58 | }) | 58 | .flat_map(|per_ns| { |
59 | per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) | ||
60 | }) | ||
59 | } | 61 | } |
60 | 62 | ||
61 | pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ { | 63 | pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ { |
@@ -110,26 +112,38 @@ impl ItemScope { | |||
110 | self.legacy_macros.insert(name, mac); | 112 | self.legacy_macros.insert(name, mac); |
111 | } | 113 | } |
112 | 114 | ||
113 | pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, declaration: bool) -> bool { | 115 | pub(crate) fn push_res( |
116 | &mut self, | ||
117 | name: Name, | ||
118 | res: &Resolution, | ||
119 | import: Option<LocalImportId>, | ||
120 | ) -> bool { | ||
114 | let mut changed = false; | 121 | let mut changed = false; |
115 | let existing = self.items.entry(name.clone()).or_default(); | 122 | let existing = self.items.entry(name.clone()).or_default(); |
116 | 123 | ||
117 | if existing.def.types.is_none() && res.def.types.is_some() { | 124 | if existing.def.types.is_none() && res.def.types.is_some() { |
118 | existing.def.types = res.def.types; | 125 | existing.def.types = res.def.types; |
119 | existing.declaration |= declaration; | 126 | existing.import = import.or(res.import); |
120 | changed = true; | 127 | changed = true; |
121 | } | 128 | } |
122 | if existing.def.values.is_none() && res.def.values.is_some() { | 129 | if existing.def.values.is_none() && res.def.values.is_some() { |
123 | existing.def.values = res.def.values; | 130 | existing.def.values = res.def.values; |
124 | existing.declaration |= declaration; | 131 | existing.import = import.or(res.import); |
125 | changed = true; | 132 | changed = true; |
126 | } | 133 | } |
127 | if existing.def.macros.is_none() && res.def.macros.is_some() { | 134 | if existing.def.macros.is_none() && res.def.macros.is_some() { |
128 | existing.def.macros = res.def.macros; | 135 | existing.def.macros = res.def.macros; |
129 | existing.declaration |= declaration; | 136 | existing.import = import.or(res.import); |
130 | changed = true; | 137 | changed = true; |
131 | } | 138 | } |
132 | 139 | ||
140 | if existing.def.is_none() | ||
141 | && res.def.is_none() | ||
142 | && existing.import.is_none() | ||
143 | && res.import.is_some() | ||
144 | { | ||
145 | existing.import = res.import; | ||
146 | } | ||
133 | changed | 147 | changed |
134 | } | 148 | } |
135 | 149 | ||
@@ -146,5 +160,6 @@ impl ItemScope { | |||
146 | pub struct Resolution { | 160 | pub struct Resolution { |
147 | /// None for unresolved | 161 | /// None for unresolved |
148 | pub def: PerNs, | 162 | pub def: PerNs, |
149 | pub declaration: bool, | 163 | /// ident by which this is imported into local scope. |
164 | pub import: Option<LocalImportId>, | ||
150 | } | 165 | } |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index f6c7f38d1..acd4f4af1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -52,6 +52,10 @@ use crate::body::Expander; | |||
52 | use crate::builtin_type::BuiltinType; | 52 | use crate::builtin_type::BuiltinType; |
53 | 53 | ||
54 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 54 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
55 | pub struct LocalImportId(RawId); | ||
56 | impl_arena_id!(LocalImportId); | ||
57 | |||
58 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
55 | pub struct ModuleId { | 59 | pub struct ModuleId { |
56 | pub krate: CrateId, | 60 | pub krate: CrateId, |
57 | pub local_id: LocalModuleId, | 61 | pub local_id: LocalModuleId, |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 9419461a8..45199fa11 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -26,7 +26,8 @@ use crate::{ | |||
26 | path::{ModPath, PathKind}, | 26 | path::{ModPath, PathKind}, |
27 | per_ns::PerNs, | 27 | per_ns::PerNs, |
28 | AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, | 28 | AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, |
29 | LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, | 29 | LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, |
30 | TypeAliasLoc, UnionLoc, | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 33 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
@@ -92,7 +93,7 @@ impl PartialResolvedImport { | |||
92 | #[derive(Clone, Debug, Eq, PartialEq)] | 93 | #[derive(Clone, Debug, Eq, PartialEq)] |
93 | struct ImportDirective { | 94 | struct ImportDirective { |
94 | module_id: LocalModuleId, | 95 | module_id: LocalModuleId, |
95 | import_id: raw::LocalImportId, | 96 | import_id: LocalImportId, |
96 | import: raw::ImportData, | 97 | import: raw::ImportData, |
97 | status: PartialResolvedImport, | 98 | status: PartialResolvedImport, |
98 | } | 99 | } |
@@ -109,7 +110,7 @@ struct MacroDirective { | |||
109 | struct DefCollector<'a, DB> { | 110 | struct DefCollector<'a, DB> { |
110 | db: &'a DB, | 111 | db: &'a DB, |
111 | def_map: CrateDefMap, | 112 | def_map: CrateDefMap, |
112 | glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, raw::LocalImportId)>>, | 113 | glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>, |
113 | unresolved_imports: Vec<ImportDirective>, | 114 | unresolved_imports: Vec<ImportDirective>, |
114 | resolved_imports: Vec<ImportDirective>, | 115 | resolved_imports: Vec<ImportDirective>, |
115 | unexpanded_macros: Vec<MacroDirective>, | 116 | unexpanded_macros: Vec<MacroDirective>, |
@@ -217,7 +218,8 @@ where | |||
217 | if export { | 218 | if export { |
218 | self.update( | 219 | self.update( |
219 | self.def_map.root, | 220 | self.def_map.root, |
220 | &[(name, Resolution { def: PerNs::macros(macro_), declaration: false })], | 221 | None, |
222 | &[(name, Resolution { def: PerNs::macros(macro_), import: None })], | ||
221 | ); | 223 | ); |
222 | } | 224 | } |
223 | } | 225 | } |
@@ -372,7 +374,7 @@ where | |||
372 | // Module scoped macros is included | 374 | // Module scoped macros is included |
373 | let items = scope.collect_resolutions(); | 375 | let items = scope.collect_resolutions(); |
374 | 376 | ||
375 | self.update(module_id, &items); | 377 | self.update(module_id, Some(import_id), &items); |
376 | } else { | 378 | } else { |
377 | // glob import from same crate => we do an initial | 379 | // glob import from same crate => we do an initial |
378 | // import, and then need to propagate any further | 380 | // import, and then need to propagate any further |
@@ -382,7 +384,7 @@ where | |||
382 | // Module scoped macros is included | 384 | // Module scoped macros is included |
383 | let items = scope.collect_resolutions(); | 385 | let items = scope.collect_resolutions(); |
384 | 386 | ||
385 | self.update(module_id, &items); | 387 | self.update(module_id, Some(import_id), &items); |
386 | // record the glob import in case we add further items | 388 | // record the glob import in case we add further items |
387 | let glob = self.glob_imports.entry(m.local_id).or_default(); | 389 | let glob = self.glob_imports.entry(m.local_id).or_default(); |
388 | if !glob.iter().any(|it| *it == (module_id, import_id)) { | 390 | if !glob.iter().any(|it| *it == (module_id, import_id)) { |
@@ -402,12 +404,12 @@ where | |||
402 | let variant = EnumVariantId { parent: e, local_id }; | 404 | let variant = EnumVariantId { parent: e, local_id }; |
403 | let res = Resolution { | 405 | let res = Resolution { |
404 | def: PerNs::both(variant.into(), variant.into()), | 406 | def: PerNs::both(variant.into(), variant.into()), |
405 | declaration: false, | 407 | import: Some(import_id), |
406 | }; | 408 | }; |
407 | (name, res) | 409 | (name, res) |
408 | }) | 410 | }) |
409 | .collect::<Vec<_>>(); | 411 | .collect::<Vec<_>>(); |
410 | self.update(module_id, &resolutions); | 412 | self.update(module_id, Some(import_id), &resolutions); |
411 | } | 413 | } |
412 | Some(d) => { | 414 | Some(d) => { |
413 | log::debug!("glob import {:?} from non-module/enum {:?}", import, d); | 415 | log::debug!("glob import {:?} from non-module/enum {:?}", import, d); |
@@ -429,21 +431,27 @@ where | |||
429 | } | 431 | } |
430 | } | 432 | } |
431 | 433 | ||
432 | let resolution = Resolution { def, declaration: false }; | 434 | let resolution = Resolution { def, import: Some(import_id) }; |
433 | self.update(module_id, &[(name, resolution)]); | 435 | self.update(module_id, Some(import_id), &[(name, resolution)]); |
434 | } | 436 | } |
435 | None => tested_by!(bogus_paths), | 437 | None => tested_by!(bogus_paths), |
436 | } | 438 | } |
437 | } | 439 | } |
438 | } | 440 | } |
439 | 441 | ||
440 | fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, Resolution)]) { | 442 | fn update( |
441 | self.update_recursive(module_id, resolutions, 0) | 443 | &mut self, |
444 | module_id: LocalModuleId, | ||
445 | import: Option<LocalImportId>, | ||
446 | resolutions: &[(Name, Resolution)], | ||
447 | ) { | ||
448 | self.update_recursive(module_id, import, resolutions, 0) | ||
442 | } | 449 | } |
443 | 450 | ||
444 | fn update_recursive( | 451 | fn update_recursive( |
445 | &mut self, | 452 | &mut self, |
446 | module_id: LocalModuleId, | 453 | module_id: LocalModuleId, |
454 | import: Option<LocalImportId>, | ||
447 | resolutions: &[(Name, Resolution)], | 455 | resolutions: &[(Name, Resolution)], |
448 | depth: usize, | 456 | depth: usize, |
449 | ) { | 457 | ) { |
@@ -454,7 +462,7 @@ where | |||
454 | let scope = &mut self.def_map.modules[module_id].scope; | 462 | let scope = &mut self.def_map.modules[module_id].scope; |
455 | let mut changed = false; | 463 | let mut changed = false; |
456 | for (name, res) in resolutions { | 464 | for (name, res) in resolutions { |
457 | changed |= scope.push_res(name.clone(), res, depth == 0 && res.declaration); | 465 | changed |= scope.push_res(name.clone(), res, import); |
458 | } | 466 | } |
459 | 467 | ||
460 | if !changed { | 468 | if !changed { |
@@ -467,9 +475,9 @@ where | |||
467 | .flat_map(|v| v.iter()) | 475 | .flat_map(|v| v.iter()) |
468 | .cloned() | 476 | .cloned() |
469 | .collect::<Vec<_>>(); | 477 | .collect::<Vec<_>>(); |
470 | for (glob_importing_module, _glob_import) in glob_imports { | 478 | for (glob_importing_module, glob_import) in glob_imports { |
471 | // We pass the glob import so that the tracked import in those modules is that glob import | 479 | // We pass the glob import so that the tracked import in those modules is that glob import |
472 | self.update_recursive(glob_importing_module, resolutions, depth + 1); | 480 | self.update_recursive(glob_importing_module, Some(glob_import), resolutions, depth + 1); |
473 | } | 481 | } |
474 | } | 482 | } |
475 | 483 | ||
@@ -711,9 +719,9 @@ where | |||
711 | def: PerNs::types( | 719 | def: PerNs::types( |
712 | ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), | 720 | ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), |
713 | ), | 721 | ), |
714 | declaration: true, | 722 | import: None, |
715 | }; | 723 | }; |
716 | self.def_collector.update(self.module_id, &[(name, resolution)]); | 724 | self.def_collector.update(self.module_id, None, &[(name, resolution)]); |
717 | res | 725 | res |
718 | } | 726 | } |
719 | 727 | ||
@@ -783,8 +791,8 @@ where | |||
783 | PerNs::types(def.into()) | 791 | PerNs::types(def.into()) |
784 | } | 792 | } |
785 | }; | 793 | }; |
786 | let resolution = Resolution { def, declaration: true }; | 794 | let resolution = Resolution { def, import: None }; |
787 | self.def_collector.update(self.module_id, &[(name, resolution)]) | 795 | self.def_collector.update(self.module_id, None, &[(name, resolution)]) |
788 | } | 796 | } |
789 | 797 | ||
790 | fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { | 798 | fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index b10e458a2..ecb4d7c03 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -7,24 +7,24 @@ | |||
7 | 7 | ||
8 | use std::{ops::Index, sync::Arc}; | 8 | use std::{ops::Index, sync::Arc}; |
9 | 9 | ||
10 | use either::Either; | ||
10 | use hir_expand::{ | 11 | use hir_expand::{ |
11 | ast_id_map::AstIdMap, | 12 | ast_id_map::AstIdMap, |
12 | db::AstDatabase, | 13 | db::AstDatabase, |
13 | hygiene::Hygiene, | 14 | hygiene::Hygiene, |
14 | name::{AsName, Name}, | 15 | name::{AsName, Name}, |
15 | }; | 16 | }; |
16 | use ra_arena::{impl_arena_id, Arena, RawId}; | 17 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; |
17 | use ra_syntax::{ | 18 | use ra_syntax::{ |
18 | ast::{self, AttrsOwner, NameOwner}, | 19 | ast::{self, AttrsOwner, NameOwner}, |
19 | AstNode, | 20 | AstNode, AstPtr, |
20 | }; | 21 | }; |
21 | use test_utils::tested_by; | 22 | use test_utils::tested_by; |
22 | 23 | ||
23 | use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; | 24 | use crate::{ |
24 | 25 | attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile, | |
25 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 26 | LocalImportId, |
26 | pub(super) struct LocalImportId(RawId); | 27 | }; |
27 | impl_arena_id!(LocalImportId); | ||
28 | 28 | ||
29 | /// `RawItems` is a set of top-level items in a file (except for impls). | 29 | /// `RawItems` is a set of top-level items in a file (except for impls). |
30 | /// | 30 | /// |
@@ -41,14 +41,35 @@ pub struct RawItems { | |||
41 | items: Vec<RawItem>, | 41 | items: Vec<RawItem>, |
42 | } | 42 | } |
43 | 43 | ||
44 | #[derive(Debug, Default, PartialEq, Eq)] | ||
45 | pub struct ImportSourceMap { | ||
46 | map: ArenaMap<LocalImportId, ImportSourcePtr>, | ||
47 | } | ||
48 | |||
49 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; | ||
50 | |||
51 | impl ImportSourceMap { | ||
52 | pub fn get(&self, import: LocalImportId) -> ImportSourcePtr { | ||
53 | self.map[import].clone() | ||
54 | } | ||
55 | } | ||
56 | |||
44 | impl RawItems { | 57 | impl RawItems { |
45 | pub(crate) fn raw_items_query( | 58 | pub(crate) fn raw_items_query( |
46 | db: &(impl DefDatabase + AstDatabase), | 59 | db: &(impl DefDatabase + AstDatabase), |
47 | file_id: HirFileId, | 60 | file_id: HirFileId, |
48 | ) -> Arc<RawItems> { | 61 | ) -> Arc<RawItems> { |
62 | db.raw_items_with_source_map(file_id).0 | ||
63 | } | ||
64 | |||
65 | pub(crate) fn raw_items_with_source_map_query( | ||
66 | db: &(impl DefDatabase + AstDatabase), | ||
67 | file_id: HirFileId, | ||
68 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { | ||
49 | let mut collector = RawItemsCollector { | 69 | let mut collector = RawItemsCollector { |
50 | raw_items: RawItems::default(), | 70 | raw_items: RawItems::default(), |
51 | source_ast_id_map: db.ast_id_map(file_id), | 71 | source_ast_id_map: db.ast_id_map(file_id), |
72 | imports: Trace::new(), | ||
52 | file_id, | 73 | file_id, |
53 | hygiene: Hygiene::new(db, file_id), | 74 | hygiene: Hygiene::new(db, file_id), |
54 | }; | 75 | }; |
@@ -59,8 +80,11 @@ impl RawItems { | |||
59 | collector.process_module(None, item_list); | 80 | collector.process_module(None, item_list); |
60 | } | 81 | } |
61 | } | 82 | } |
62 | let raw_items = collector.raw_items; | 83 | let mut raw_items = collector.raw_items; |
63 | Arc::new(raw_items) | 84 | let (arena, map) = collector.imports.into_arena_and_map(); |
85 | raw_items.imports = arena; | ||
86 | let source_map = ImportSourceMap { map }; | ||
87 | (Arc::new(raw_items), Arc::new(source_map)) | ||
64 | } | 88 | } |
65 | 89 | ||
66 | pub(super) fn items(&self) -> &[RawItem] { | 90 | pub(super) fn items(&self) -> &[RawItem] { |
@@ -199,6 +223,7 @@ pub(super) struct ImplData { | |||
199 | 223 | ||
200 | struct RawItemsCollector { | 224 | struct RawItemsCollector { |
201 | raw_items: RawItems, | 225 | raw_items: RawItems, |
226 | imports: Trace<LocalImportId, ImportData, ImportSourcePtr>, | ||
202 | source_ast_id_map: Arc<AstIdMap>, | 227 | source_ast_id_map: Arc<AstIdMap>, |
203 | file_id: HirFileId, | 228 | file_id: HirFileId, |
204 | hygiene: Hygiene, | 229 | hygiene: Hygiene, |
@@ -305,7 +330,7 @@ impl RawItemsCollector { | |||
305 | ModPath::expand_use_item( | 330 | ModPath::expand_use_item( |
306 | InFile { value: use_item, file_id: self.file_id }, | 331 | InFile { value: use_item, file_id: self.file_id }, |
307 | &self.hygiene, | 332 | &self.hygiene, |
308 | |path, _use_tree, is_glob, alias| { | 333 | |path, use_tree, is_glob, alias| { |
309 | let import_data = ImportData { | 334 | let import_data = ImportData { |
310 | path, | 335 | path, |
311 | alias, | 336 | alias, |
@@ -314,11 +339,11 @@ impl RawItemsCollector { | |||
314 | is_extern_crate: false, | 339 | is_extern_crate: false, |
315 | is_macro_use: false, | 340 | is_macro_use: false, |
316 | }; | 341 | }; |
317 | buf.push(import_data); | 342 | buf.push((import_data, Either::Left(AstPtr::new(use_tree)))); |
318 | }, | 343 | }, |
319 | ); | 344 | ); |
320 | for import_data in buf { | 345 | for (import_data, ptr) in buf { |
321 | self.push_import(current_module, attrs.clone(), import_data); | 346 | self.push_import(current_module, attrs.clone(), import_data, ptr); |
322 | } | 347 | } |
323 | } | 348 | } |
324 | 349 | ||
@@ -341,7 +366,12 @@ impl RawItemsCollector { | |||
341 | is_extern_crate: true, | 366 | is_extern_crate: true, |
342 | is_macro_use, | 367 | is_macro_use, |
343 | }; | 368 | }; |
344 | self.push_import(current_module, attrs, import_data); | 369 | self.push_import( |
370 | current_module, | ||
371 | attrs, | ||
372 | import_data, | ||
373 | Either::Right(AstPtr::new(&extern_crate)), | ||
374 | ); | ||
345 | } | 375 | } |
346 | } | 376 | } |
347 | 377 | ||
@@ -372,8 +402,14 @@ impl RawItemsCollector { | |||
372 | self.push_item(current_module, attrs, RawItemKind::Impl(imp)) | 402 | self.push_item(current_module, attrs, RawItemKind::Impl(imp)) |
373 | } | 403 | } |
374 | 404 | ||
375 | fn push_import(&mut self, current_module: Option<Module>, attrs: Attrs, data: ImportData) { | 405 | fn push_import( |
376 | let import = self.raw_items.imports.alloc(data); | 406 | &mut self, |
407 | current_module: Option<Module>, | ||
408 | attrs: Attrs, | ||
409 | data: ImportData, | ||
410 | source: ImportSourcePtr, | ||
411 | ) { | ||
412 | let import = self.imports.alloc(|| source, || data); | ||
377 | self.push_item(current_module, attrs, RawItemKind::Import(import)) | 413 | self.push_item(current_module, attrs, RawItemKind::Import(import)) |
378 | } | 414 | } |
379 | 415 | ||
diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs index 9769e88df..2bcd707bc 100644 --- a/crates/ra_hir_def/src/trace.rs +++ b/crates/ra_hir_def/src/trace.rs | |||
@@ -18,6 +18,10 @@ pub(crate) struct Trace<ID: ArenaId, T, V> { | |||
18 | } | 18 | } |
19 | 19 | ||
20 | impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> { | 20 | impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> { |
21 | pub(crate) fn new() -> Trace<ID, T, V> { | ||
22 | Trace { arena: Some(Arena::default()), map: Some(ArenaMap::default()), len: 0 } | ||
23 | } | ||
24 | |||
21 | pub(crate) fn new_for_arena() -> Trace<ID, T, V> { | 25 | pub(crate) fn new_for_arena() -> Trace<ID, T, V> { |
22 | Trace { arena: Some(Arena::default()), map: None, len: 0 } | 26 | Trace { arena: Some(Arena::default()), map: None, len: 0 } |
23 | } | 27 | } |
@@ -48,4 +52,8 @@ impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> { | |||
48 | pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> { | 52 | pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> { |
49 | self.map.take().unwrap() | 53 | self.map.take().unwrap() |
50 | } | 54 | } |
55 | |||
56 | pub(crate) fn into_arena_and_map(mut self) -> (Arena<ID, T>, ArenaMap<ID, V>) { | ||
57 | (self.arena.take().unwrap(), self.map.take().unwrap()) | ||
58 | } | ||
51 | } | 59 | } |
diff --git a/crates/ra_ide/src/change.rs b/crates/ra_ide/src/change.rs index 387a9cafb..4a76d1dd8 100644 --- a/crates/ra_ide/src/change.rs +++ b/crates/ra_ide/src/change.rs | |||
@@ -270,6 +270,7 @@ impl RootDatabase { | |||
270 | 270 | ||
271 | self.query(hir::db::AstIdMapQuery).sweep(sweep); | 271 | self.query(hir::db::AstIdMapQuery).sweep(sweep); |
272 | 272 | ||
273 | self.query(hir::db::RawItemsWithSourceMapQuery).sweep(sweep); | ||
273 | self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep); | 274 | self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep); |
274 | 275 | ||
275 | self.query(hir::db::ExprScopesQuery).sweep(sweep); | 276 | self.query(hir::db::ExprScopesQuery).sweep(sweep); |
@@ -308,6 +309,7 @@ impl RootDatabase { | |||
308 | hir::db::StructDataQuery | 309 | hir::db::StructDataQuery |
309 | hir::db::EnumDataQuery | 310 | hir::db::EnumDataQuery |
310 | hir::db::TraitDataQuery | 311 | hir::db::TraitDataQuery |
312 | hir::db::RawItemsWithSourceMapQuery | ||
311 | hir::db::RawItemsQuery | 313 | hir::db::RawItemsQuery |
312 | hir::db::CrateDefMapQuery | 314 | hir::db::CrateDefMapQuery |
313 | hir::db::GenericParamsQuery | 315 | hir::db::GenericParamsQuery |
diff --git a/crates/ra_ide/src/completion/complete_path.rs b/crates/ra_ide/src/completion/complete_path.rs index 8ce86ad7d..28f94e0a7 100644 --- a/crates/ra_ide/src/completion/complete_path.rs +++ b/crates/ra_ide/src/completion/complete_path.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{Adt, PathResolution, ScopeDef}; | 3 | use either::Either; |
4 | use hir::{Adt, HasSource, PathResolution}; | ||
4 | use ra_syntax::AstNode; | 5 | use ra_syntax::AstNode; |
5 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
6 | 7 | ||
@@ -18,15 +19,17 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
18 | match def { | 19 | match def { |
19 | hir::ModuleDef::Module(module) => { | 20 | hir::ModuleDef::Module(module) => { |
20 | let module_scope = module.scope(ctx.db); | 21 | let module_scope = module.scope(ctx.db); |
21 | for (name, def) in module_scope { | 22 | for (name, def, import) in module_scope { |
22 | if ctx.use_item_syntax.is_some() { | 23 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::BuiltinType(..)) = def { |
23 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::BuiltinType(..)) = def { | 24 | if ctx.use_item_syntax.is_some() { |
24 | tested_by!(dont_complete_primitive_in_use); | 25 | tested_by!(dont_complete_primitive_in_use); |
25 | continue; | 26 | continue; |
26 | } | 27 | } |
27 | if let ScopeDef::Unknown = def { | 28 | } |
28 | if let Some(name_ref) = ctx.name_ref.as_ref() { | 29 | if Some(module) == ctx.module { |
29 | if &name_ref.syntax().text() == name.to_string().as_str() { | 30 | if let Some(import) = import { |
31 | if let Either::Left(use_tree) = import.source(ctx.db).value { | ||
32 | if use_tree.syntax().text_range().contains_inclusive(ctx.offset) { | ||
30 | // for `use self::foo<|>`, don't suggest `foo` as a completion | 33 | // for `use self::foo<|>`, don't suggest `foo` as a completion |
31 | tested_by!(dont_complete_current_use); | 34 | tested_by!(dont_complete_current_use); |
32 | continue; | 35 | continue; |
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 8f56ce706..4894ea2f6 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs | |||
@@ -18,7 +18,6 @@ pub(crate) struct CompletionContext<'a> { | |||
18 | pub(super) analyzer: hir::SourceAnalyzer, | 18 | pub(super) analyzer: hir::SourceAnalyzer, |
19 | pub(super) offset: TextUnit, | 19 | pub(super) offset: TextUnit, |
20 | pub(super) token: SyntaxToken, | 20 | pub(super) token: SyntaxToken, |
21 | pub(super) name_ref: Option<ast::NameRef>, | ||
22 | pub(super) module: Option<hir::Module>, | 21 | pub(super) module: Option<hir::Module>, |
23 | pub(super) function_syntax: Option<ast::FnDef>, | 22 | pub(super) function_syntax: Option<ast::FnDef>, |
24 | pub(super) use_item_syntax: Option<ast::UseItem>, | 23 | pub(super) use_item_syntax: Option<ast::UseItem>, |
@@ -69,7 +68,6 @@ impl<'a> CompletionContext<'a> { | |||
69 | analyzer, | 68 | analyzer, |
70 | token, | 69 | token, |
71 | offset: position.offset, | 70 | offset: position.offset, |
72 | name_ref: None, | ||
73 | module, | 71 | module, |
74 | function_syntax: None, | 72 | function_syntax: None, |
75 | use_item_syntax: None, | 73 | use_item_syntax: None, |
@@ -144,8 +142,6 @@ impl<'a> CompletionContext<'a> { | |||
144 | } | 142 | } |
145 | 143 | ||
146 | fn classify_name_ref(&mut self, original_file: SourceFile, name_ref: ast::NameRef) { | 144 | fn classify_name_ref(&mut self, original_file: SourceFile, name_ref: ast::NameRef) { |
147 | self.name_ref = | ||
148 | find_node_at_offset(original_file.syntax(), name_ref.syntax().text_range().start()); | ||
149 | let name_range = name_ref.syntax().text_range(); | 145 | let name_range = name_ref.syntax().text_range(); |
150 | if name_ref.syntax().parent().and_then(ast::RecordField::cast).is_some() { | 146 | if name_ref.syntax().parent().and_then(ast::RecordField::cast).is_some() { |
151 | self.record_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset); | 147 | self.record_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset); |