aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/code_model_api.rs4
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs4
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/nameres.rs7
-rw-r--r--crates/ra_hir/src/nameres/raw.rs69
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs13
6 files changed, 70 insertions, 29 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 46455bd83..87d81f4a4 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -4,7 +4,7 @@ use ra_db::{CrateId, SourceRootId, Edition};
4use ra_syntax::{ast::self, TreeArc}; 4use ra_syntax::{ast::self, TreeArc};
5 5
6use crate::{ 6use crate::{
7 Name, ScopesWithSourceMap, Ty, HirFileId, 7 Name, ScopesWithSourceMap, Ty, HirFileId, ImportSource,
8 HirDatabase, DefDatabase, 8 HirDatabase, DefDatabase,
9 type_ref::TypeRef, 9 type_ref::TypeRef,
10 nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, 10 nameres::{ModuleScope, Namespace, ImportId, CrateModuleId},
@@ -117,7 +117,7 @@ impl Module {
117 } 117 }
118 118
119 /// Returns the syntax of the last path segment corresponding to this import 119 /// Returns the syntax of the last path segment corresponding to this import
120 pub fn import_source(&self, db: &impl HirDatabase, import: ImportId) -> TreeArc<ast::UseTree> { 120 pub fn import_source(&self, db: &impl HirDatabase, import: ImportId) -> ImportSource {
121 self.import_source_impl(db, import) 121 self.import_source_impl(db, import)
122 } 122 }
123 123
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index ccca2b7e5..88dee3a69 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -5,7 +5,7 @@ use crate::{
5 Module, ModuleSource, Name, AstId, 5 Module, ModuleSource, Name, AstId,
6 nameres::{CrateModuleId, ImportId}, 6 nameres::{CrateModuleId, ImportId},
7 HirDatabase, DefDatabase, 7 HirDatabase, DefDatabase,
8 HirFileId, 8 HirFileId, ImportSource,
9}; 9};
10 10
11impl ModuleSource { 11impl ModuleSource {
@@ -72,7 +72,7 @@ impl Module {
72 &self, 72 &self,
73 db: &impl HirDatabase, 73 db: &impl HirDatabase,
74 import: ImportId, 74 import: ImportId,
75 ) -> TreeArc<ast::UseTree> { 75 ) -> ImportSource {
76 let (file_id, source) = self.definition_source(db); 76 let (file_id, source) = self.definition_source(db);
77 let (_, source_map) = db.raw_items_with_source_map(file_id); 77 let (_, source_map) = db.raw_items_with_source_map(file_id);
78 source_map.get(&source, import) 78 source_map.get(&source, import)
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 7c603bbd3..643bee6cd 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -56,7 +56,7 @@ pub use self::{
56 name::Name, 56 name::Name,
57 source_id::{AstIdMap, ErasedFileAstId}, 57 source_id::{AstIdMap, ErasedFileAstId},
58 ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner}, 58 ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner},
59 nameres::{PerNs, Namespace}, 59 nameres::{PerNs, Namespace, ImportId, ImportSource},
60 ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, 60 ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay},
61 impl_block::{ImplBlock, ImplItem}, 61 impl_block::{ImplBlock, ImplItem},
62 docs::{Docs, Documentation}, 62 docs::{Docs, Documentation},
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index 67b9d6986..6f049acfc 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -70,9 +70,12 @@ use crate::{
70 AstId, 70 AstId,
71}; 71};
72 72
73pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; 73pub(crate) use self::raw::{RawItems, ImportSourceMap};
74 74
75pub use self::per_ns::{PerNs, Namespace}; 75pub use self::{
76 per_ns::{PerNs, Namespace},
77 raw::{ImportId, ImportSource},
78};
76 79
77/// Contans all top-level defs from a macro-expanded crate 80/// Contans all top-level defs from a macro-expanded crate
78#[derive(Debug, PartialEq, Eq)] 81#[derive(Debug, PartialEq, Eq)]
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 35cbe6655..b7416ede6 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -31,21 +31,43 @@ pub struct RawItems {
31 31
32#[derive(Debug, Default, PartialEq, Eq)] 32#[derive(Debug, Default, PartialEq, Eq)]
33pub struct ImportSourceMap { 33pub struct ImportSourceMap {
34 map: ArenaMap<ImportId, AstPtr<ast::UseTree>>, 34 map: ArenaMap<ImportId, ImportSourcePtr>,
35}
36
37#[derive(Debug, PartialEq, Eq, Clone, Copy)]
38enum ImportSourcePtr {
39 UseTree(AstPtr<ast::UseTree>),
40 ExternCrate(AstPtr<ast::ExternCrateItem>),
41}
42
43impl ImportSourcePtr {
44 fn to_node(self, file: &SourceFile) -> ImportSource {
45 match self {
46 ImportSourcePtr::UseTree(ptr) => ImportSource::UseTree(ptr.to_node(file).to_owned()),
47 ImportSourcePtr::ExternCrate(ptr) => {
48 ImportSource::ExternCrate(ptr.to_node(file).to_owned())
49 }
50 }
51 }
52}
53
54pub enum ImportSource {
55 UseTree(TreeArc<ast::UseTree>),
56 ExternCrate(TreeArc<ast::ExternCrateItem>),
35} 57}
36 58
37impl ImportSourceMap { 59impl ImportSourceMap {
38 fn insert(&mut self, import: ImportId, use_tree: &ast::UseTree) { 60 fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) {
39 self.map.insert(import, AstPtr::new(use_tree)) 61 self.map.insert(import, ptr)
40 } 62 }
41 63
42 pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc<ast::UseTree> { 64 pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> ImportSource {
43 let file = match source { 65 let file = match source {
44 ModuleSource::SourceFile(file) => &*file, 66 ModuleSource::SourceFile(file) => &*file,
45 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), 67 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
46 }; 68 };
47 69
48 self.map[import].to_node(file).to_owned() 70 self.map[import].to_node(file)
49 } 71 }
50} 72}
51 73
@@ -257,15 +279,13 @@ impl RawItemsCollector {
257 let is_prelude = use_item.has_atom_attr("prelude_import"); 279 let is_prelude = use_item.has_atom_attr("prelude_import");
258 280
259 Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| { 281 Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| {
260 let import = self.raw_items.imports.alloc(ImportData { 282 let import_data =
261 path, 283 ImportData { path, alias, is_glob, is_prelude, is_extern_crate: false };
262 alias, 284 self.push_import(
263 is_glob, 285 current_module,
264 is_prelude, 286 import_data,
265 is_extern_crate: false, 287 ImportSourcePtr::UseTree(AstPtr::new(use_tree)),
266 }); 288 );
267 self.source_map.insert(import, use_tree);
268 self.push_item(current_module, RawItem::Import(import))
269 }) 289 })
270 } 290 }
271 291
@@ -277,14 +297,18 @@ impl RawItemsCollector {
277 if let Some(name_ref) = extern_crate.name_ref() { 297 if let Some(name_ref) = extern_crate.name_ref() {
278 let path = Path::from_name_ref(name_ref); 298 let path = Path::from_name_ref(name_ref);
279 let alias = extern_crate.alias().and_then(|a| a.name()).map(AsName::as_name); 299 let alias = extern_crate.alias().and_then(|a| a.name()).map(AsName::as_name);
280 let import = self.raw_items.imports.alloc(ImportData { 300 let import_data = ImportData {
281 path, 301 path,
282 alias, 302 alias,
283 is_glob: false, 303 is_glob: false,
284 is_prelude: false, 304 is_prelude: false,
285 is_extern_crate: true, 305 is_extern_crate: true,
286 }); 306 };
287 self.push_item(current_module, RawItem::Import(import)) 307 self.push_import(
308 current_module,
309 import_data,
310 ImportSourcePtr::ExternCrate(AstPtr::new(extern_crate)),
311 );
288 } 312 }
289 } 313 }
290 314
@@ -301,6 +325,17 @@ impl RawItemsCollector {
301 self.push_item(current_module, RawItem::Macro(m)); 325 self.push_item(current_module, RawItem::Macro(m));
302 } 326 }
303 327
328 fn push_import(
329 &mut self,
330 current_module: Option<Module>,
331 data: ImportData,
332 source: ImportSourcePtr,
333 ) {
334 let import = self.raw_items.imports.alloc(data);
335 self.source_map.insert(import, source);
336 self.push_item(current_module, RawItem::Import(import))
337 }
338
304 fn push_item(&mut self, current_module: Option<Module>, item: RawItem) { 339 fn push_item(&mut self, current_module: Option<Module>, item: RawItem) {
305 match current_module { 340 match current_module {
306 Some(module) => match &mut self.raw_items.modules[module] { 341 Some(module) => match &mut self.raw_items.modules[module] {
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 122dd7bdd..e54fe7b7e 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -19,11 +19,14 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
19 for (name, res) in module_scope.entries() { 19 for (name, res) in module_scope.entries() {
20 if Some(module) == ctx.module { 20 if Some(module) == ctx.module {
21 if let Some(import) = res.import { 21 if let Some(import) = res.import {
22 let path = module.import_source(ctx.db, import); 22 if let hir::ImportSource::UseTree(tree) =
23 if path.syntax().range().contains_inclusive(ctx.offset) { 23 module.import_source(ctx.db, import)
24 // for `use self::foo<|>`, don't suggest `foo` as a completion 24 {
25 tested_by!(dont_complete_current_use); 25 if tree.syntax().range().contains_inclusive(ctx.offset) {
26 continue; 26 // for `use self::foo<|>`, don't suggest `foo` as a completion
27 tested_by!(dont_complete_current_use);
28 continue;
29 }
27 } 30 }
28 } 31 }
29 } 32 }