From 0de89f786ffd71d56317853e1f3360f33b8e2ddf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Apr 2019 17:58:04 +0300 Subject: always produce source for import --- crates/ra_hir/src/code_model_api.rs | 4 +- crates/ra_hir/src/code_model_impl/module.rs | 4 +- crates/ra_hir/src/lib.rs | 2 +- crates/ra_hir/src/nameres.rs | 7 ++- crates/ra_hir/src/nameres/raw.rs | 69 +++++++++++++++++------ crates/ra_ide_api/src/completion/complete_path.rs | 13 +++-- 6 files changed, 70 insertions(+), 29 deletions(-) (limited to 'crates') 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}; use ra_syntax::{ast::self, TreeArc}; use crate::{ - Name, ScopesWithSourceMap, Ty, HirFileId, + Name, ScopesWithSourceMap, Ty, HirFileId, ImportSource, HirDatabase, DefDatabase, type_ref::TypeRef, nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, @@ -117,7 +117,7 @@ impl Module { } /// Returns the syntax of the last path segment corresponding to this import - pub fn import_source(&self, db: &impl HirDatabase, import: ImportId) -> TreeArc { + pub fn import_source(&self, db: &impl HirDatabase, import: ImportId) -> ImportSource { self.import_source_impl(db, import) } 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::{ Module, ModuleSource, Name, AstId, nameres::{CrateModuleId, ImportId}, HirDatabase, DefDatabase, - HirFileId, + HirFileId, ImportSource, }; impl ModuleSource { @@ -72,7 +72,7 @@ impl Module { &self, db: &impl HirDatabase, import: ImportId, - ) -> TreeArc { + ) -> ImportSource { let (file_id, source) = self.definition_source(db); let (_, source_map) = db.raw_items_with_source_map(file_id); 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::{ name::Name, source_id::{AstIdMap, ErasedFileAstId}, ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner}, - nameres::{PerNs, Namespace}, + nameres::{PerNs, Namespace, ImportId, ImportSource}, ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, impl_block::{ImplBlock, ImplItem}, 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::{ AstId, }; -pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; +pub(crate) use self::raw::{RawItems, ImportSourceMap}; -pub use self::per_ns::{PerNs, Namespace}; +pub use self::{ + per_ns::{PerNs, Namespace}, + raw::{ImportId, ImportSource}, +}; /// Contans all top-level defs from a macro-expanded crate #[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 { #[derive(Debug, Default, PartialEq, Eq)] pub struct ImportSourceMap { - map: ArenaMap>, + map: ArenaMap, +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +enum ImportSourcePtr { + UseTree(AstPtr), + ExternCrate(AstPtr), +} + +impl ImportSourcePtr { + fn to_node(self, file: &SourceFile) -> ImportSource { + match self { + ImportSourcePtr::UseTree(ptr) => ImportSource::UseTree(ptr.to_node(file).to_owned()), + ImportSourcePtr::ExternCrate(ptr) => { + ImportSource::ExternCrate(ptr.to_node(file).to_owned()) + } + } + } +} + +pub enum ImportSource { + UseTree(TreeArc), + ExternCrate(TreeArc), } impl ImportSourceMap { - fn insert(&mut self, import: ImportId, use_tree: &ast::UseTree) { - self.map.insert(import, AstPtr::new(use_tree)) + fn insert(&mut self, import: ImportId, ptr: ImportSourcePtr) { + self.map.insert(import, ptr) } - pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc { + pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> ImportSource { let file = match source { ModuleSource::SourceFile(file) => &*file, ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), }; - self.map[import].to_node(file).to_owned() + self.map[import].to_node(file) } } @@ -257,15 +279,13 @@ impl RawItemsCollector { let is_prelude = use_item.has_atom_attr("prelude_import"); Path::expand_use_item(use_item, |path, use_tree, is_glob, alias| { - let import = self.raw_items.imports.alloc(ImportData { - path, - alias, - is_glob, - is_prelude, - is_extern_crate: false, - }); - self.source_map.insert(import, use_tree); - self.push_item(current_module, RawItem::Import(import)) + let import_data = + ImportData { path, alias, is_glob, is_prelude, is_extern_crate: false }; + self.push_import( + current_module, + import_data, + ImportSourcePtr::UseTree(AstPtr::new(use_tree)), + ); }) } @@ -277,14 +297,18 @@ impl RawItemsCollector { if let Some(name_ref) = extern_crate.name_ref() { let path = Path::from_name_ref(name_ref); let alias = extern_crate.alias().and_then(|a| a.name()).map(AsName::as_name); - let import = self.raw_items.imports.alloc(ImportData { + let import_data = ImportData { path, alias, is_glob: false, is_prelude: false, is_extern_crate: true, - }); - self.push_item(current_module, RawItem::Import(import)) + }; + self.push_import( + current_module, + import_data, + ImportSourcePtr::ExternCrate(AstPtr::new(extern_crate)), + ); } } @@ -301,6 +325,17 @@ impl RawItemsCollector { self.push_item(current_module, RawItem::Macro(m)); } + fn push_import( + &mut self, + current_module: Option, + data: ImportData, + source: ImportSourcePtr, + ) { + let import = self.raw_items.imports.alloc(data); + self.source_map.insert(import, source); + self.push_item(current_module, RawItem::Import(import)) + } + fn push_item(&mut self, current_module: Option, item: RawItem) { match current_module { 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) { for (name, res) in module_scope.entries() { if Some(module) == ctx.module { if let Some(import) = res.import { - let path = module.import_source(ctx.db, import); - if path.syntax().range().contains_inclusive(ctx.offset) { - // for `use self::foo<|>`, don't suggest `foo` as a completion - tested_by!(dont_complete_current_use); - continue; + if let hir::ImportSource::UseTree(tree) = + module.import_source(ctx.db, import) + { + if tree.syntax().range().contains_inclusive(ctx.offset) { + // for `use self::foo<|>`, don't suggest `foo` as a completion + tested_by!(dont_complete_current_use); + continue; + } } } } -- cgit v1.2.3