From 049f8df93cca05af395ce873738dc85d5a25f3fc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 21 Nov 2018 12:57:05 +0300 Subject: switch completion to new scope --- crates/ra_analysis/src/completion/mod.rs | 10 +- .../src/completion/reference_completion.rs | 26 +++-- crates/ra_analysis/src/db.rs | 3 +- crates/ra_analysis/src/descriptors/mod.rs | 6 +- crates/ra_analysis/src/descriptors/module/imp.rs | 21 +--- crates/ra_analysis/src/descriptors/module/mod.rs | 9 +- .../ra_analysis/src/descriptors/module/nameres.rs | 60 +++++----- crates/ra_analysis/src/descriptors/module/scope.rs | 124 --------------------- 8 files changed, 65 insertions(+), 194 deletions(-) delete mode 100644 crates/ra_analysis/src/descriptors/module/scope.rs (limited to 'crates/ra_analysis/src') diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion/mod.rs index 5e3ee79dd..a8a752fc7 100644 --- a/crates/ra_analysis/src/completion/mod.rs +++ b/crates/ra_analysis/src/completion/mod.rs @@ -204,9 +204,9 @@ mod tests { <|> } ", - r#"[CompletionItem { label: "Foo", lookup: None, snippet: None }, - CompletionItem { label: "Baz", lookup: None, snippet: None }, - CompletionItem { label: "quux", lookup: None, snippet: None }]"#, + r#"[CompletionItem { label: "quux", lookup: None, snippet: None }, + CompletionItem { label: "Foo", lookup: None, snippet: None }, + CompletionItem { label: "Baz", lookup: None, snippet: None }]"#, ); } @@ -230,8 +230,8 @@ mod tests { fn quux() { <|> } } ", - r#"[CompletionItem { label: "Bar", lookup: None, snippet: None }, - CompletionItem { label: "quux", lookup: None, snippet: None }]"#, + r#"[CompletionItem { label: "quux", lookup: None, snippet: None }, + CompletionItem { label: "Bar", lookup: None, snippet: None }]"#, ); } diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index c94d9af75..84383b547 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs @@ -39,14 +39,17 @@ pub(super) fn completions( let module_scope = module.scope(db)?; acc.extend( module_scope - .entries() + .items .iter() - .filter(|entry| { + .filter(|(_name, res)| { // Don't expose this item - !entry.ptr().range().is_subrange(&name_ref.syntax().range()) + match res.import_name { + None => true, + Some(ptr) => !ptr.range().is_subrange(&name_ref.syntax().range()), + } }) - .map(|entry| CompletionItem { - label: entry.name().to_string(), + .map(|(name, _res)| CompletionItem { + label: name.to_string(), lookup: None, snippet: None, }), @@ -173,11 +176,14 @@ fn complete_path( Some(it) => it, }; let module_scope = target_module.scope(db)?; - let completions = module_scope.entries().iter().map(|entry| CompletionItem { - label: entry.name().to_string(), - lookup: None, - snippet: None, - }); + let completions = module_scope + .items + .iter() + .map(|(name, _res)| CompletionItem { + label: name.to_string(), + lookup: None, + snippet: None, + }); acc.extend(completions); Ok(()) } diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 9a5cd4b24..887d687ea 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs @@ -7,7 +7,7 @@ use salsa::{self, Database}; use crate::{ db, descriptors::{ - DescriptorDatabase, FnScopesQuery, FnSyntaxQuery, ModuleScopeQuery, ModuleTreeQuery, + DescriptorDatabase, FnScopesQuery, FnSyntaxQuery, ModuleTreeQuery, SubmodulesQuery, ItemMapQuery, InputModuleItemsQuery, }, symbol_index::SymbolIndex, @@ -88,7 +88,6 @@ salsa::database_storage! { fn fn_scopes() for FnScopesQuery; fn _input_module_items() for InputModuleItemsQuery; fn _item_map() for ItemMapQuery; - fn _module_scope() for ModuleScopeQuery; fn _fn_syntax() for FnSyntaxQuery; fn _submodules() for SubmodulesQuery; } diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index a32042b84..6b56d92e1 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs @@ -11,7 +11,7 @@ use ra_syntax::{ use crate::{ db::SyntaxDatabase, descriptors::function::{resolve_local_name, FnId, FnScopes}, - descriptors::module::{ModuleId, ModuleScope, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems}}, + descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems}}, input::SourceRootId, loc2id::IdDatabase, syntax_ptr::LocalSyntaxPtr, @@ -37,10 +37,6 @@ salsa::query_group! { type ModuleTreeQuery; use fn module::imp::module_tree; } - fn _module_scope(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable> { - type ModuleScopeQuery; - use fn module::imp::module_scope; - } fn _fn_syntax(fn_id: FnId) -> FnDefNode { type FnSyntaxQuery; // Don't retain syntax trees in memory diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index defe87216..d4dce861f 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use ra_syntax::{ - ast::{self, ModuleItemOwner, NameOwner}, + ast::{self, NameOwner}, SmolStr, }; use relative_path::RelativePathBuf; @@ -15,7 +15,7 @@ use crate::{ }; use super::{ - LinkData, LinkId, ModuleData, ModuleId, ModuleScope, ModuleSource, ModuleSourceNode, + LinkData, LinkId, ModuleData, ModuleId, ModuleSource, ModuleSourceNode, ModuleTree, Problem, }; @@ -81,23 +81,6 @@ pub(crate) fn modules<'a>( }) } -pub(crate) fn module_scope( - db: &impl DescriptorDatabase, - source_root_id: SourceRootId, - module_id: ModuleId, -) -> Cancelable> { - let tree = db._module_tree(source_root_id)?; - let source = module_id.source(&tree).resolve(db); - let res = match source { - ModuleSourceNode::SourceFile(it) => ModuleScope::new(it.borrowed().items()), - ModuleSourceNode::Module(it) => match it.borrowed().item_list() { - Some(items) => ModuleScope::new(items.items()), - None => ModuleScope::new(std::iter::empty()), - }, - }; - Ok(Arc::new(res)) -} - pub(crate) fn module_tree( db: &impl DescriptorDatabase, source_root: SourceRootId, diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 95d9bcc27..cfdffcdbc 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -1,5 +1,4 @@ pub(super) mod imp; -mod scope; pub(super) mod nameres; use std::sync::Arc; @@ -19,7 +18,7 @@ use crate::{ input::SourceRootId }; -pub(crate) use self::scope::ModuleScope; +pub(crate) use self::{nameres::ModuleScope}; /// `ModuleDescriptor` is API entry point to get all the information /// about a particular module. @@ -126,8 +125,10 @@ impl ModuleDescriptor { } /// Returns a `ModuleScope`: a set of items, visible in this module. - pub fn scope(&self, db: &impl DescriptorDatabase) -> Cancelable> { - db._module_scope(self.source_root_id, self.module_id) + pub(crate) fn scope(&self, db: &impl DescriptorDatabase) -> Cancelable { + let item_map = db._item_map(self.source_root_id)?; + let res = item_map.per_module[&self.module_id].clone(); + Ok(res) } pub fn problems(&self, db: &impl DescriptorDatabase) -> Vec<(SyntaxNode, Problem)> { diff --git a/crates/ra_analysis/src/descriptors/module/nameres.rs b/crates/ra_analysis/src/descriptors/module/nameres.rs index 34127e78f..c5bf467ca 100644 --- a/crates/ra_analysis/src/descriptors/module/nameres.rs +++ b/crates/ra_analysis/src/descriptors/module/nameres.rs @@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; use ra_syntax::{ SmolStr, SyntaxKind::{self, *}, - ast::{self, NameOwner, AstNode, ModuleItemOwner} + ast::{self, AstNode, ModuleItemOwner} }; use crate::{ @@ -26,13 +26,13 @@ use crate::{ /// module, the set of visible items. #[derive(Default, Debug, PartialEq, Eq)] pub(crate) struct ItemMap { - per_module: FxHashMap, + pub(crate) per_module: FxHashMap, } -#[derive(Debug, Default, PartialEq, Eq)] -struct ModuleItems { - items: FxHashMap, - import_resolutions: FxHashMap, +#[derive(Debug, Default, PartialEq, Eq, Clone)] +pub(crate) struct ModuleScope { + pub(crate) items: FxHashMap, + pub(crate) import_resolutions: FxHashMap, } /// A set of items and imports declared inside a module, without relation to @@ -117,22 +117,25 @@ pub(crate) fn item_map( /// Resolution is basically `DefId` atm, but it should account for stuff like /// multiple namespaces, ambiguity and errors. #[derive(Debug, Clone, PartialEq, Eq)] -struct Resolution { +pub(crate) struct Resolution { /// None for unresolved - def_id: Option, + pub(crate) def_id: Option, + /// ident by whitch this is imported into local scope. + /// TODO: make this offset-independent. + pub(crate) import_name: Option, } -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -enum Namespace { - Types, - Values, -} +// #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +// enum Namespace { +// Types, +// Values, +// } -#[derive(Debug)] -struct PerNs { - types: Option, - values: Option, -} +// #[derive(Debug)] +// struct PerNs { +// types: Option, +// values: Option, +// } #[derive(Debug, PartialEq, Eq)] struct ModuleItem { @@ -144,7 +147,7 @@ struct ModuleItem { #[derive(Debug, PartialEq, Eq)] enum Vis { - Priv, + // Priv, Other, } @@ -302,13 +305,17 @@ where fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) { let file_id = module_id.source(&self.module_tree).file_id(); - let mut module_items = ModuleItems::default(); + let mut module_items = ModuleScope::default(); for import in input.imports.iter() { - if let Some((_, name)) = import.segments.last() { - module_items - .items - .insert(name.clone(), Resolution { def_id: None }); + if let Some((ptr, name)) = import.segments.last() { + module_items.items.insert( + name.clone(), + Resolution { + def_id: None, + import_name: Some(*ptr), + }, + ); } } @@ -322,6 +329,7 @@ where let def_id = self.db.id_maps().def_id(def_loc); let resolution = Resolution { def_id: Some(def_id), + import_name: None, }; module_items.items.insert(item.name.clone(), resolution); } @@ -334,6 +342,7 @@ where let def_id = self.db.id_maps().def_id(def_loc); let resolution = Resolution { def_id: Some(def_id), + import_name: None, }; module_items.items.insert(name, resolution); } @@ -386,6 +395,7 @@ where self.update(module_id, |items| { let res = Resolution { def_id: Some(def_id), + import_name: Some(*ptr), }; items.items.insert(name.clone(), res); }) @@ -393,7 +403,7 @@ where } } - fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleItems)) { + fn update(&mut self, module_id: ModuleId, f: impl FnOnce(&mut ModuleScope)) { let module_items = self.result.per_module.get_mut(&module_id).unwrap(); f(module_items) } diff --git a/crates/ra_analysis/src/descriptors/module/scope.rs b/crates/ra_analysis/src/descriptors/module/scope.rs deleted file mode 100644 index 4490228e4..000000000 --- a/crates/ra_analysis/src/descriptors/module/scope.rs +++ /dev/null @@ -1,124 +0,0 @@ -//! Backend for module-level scope resolution & completion - -use ra_syntax::{ast, AstNode, SmolStr}; - -use crate::syntax_ptr::LocalSyntaxPtr; - -/// `ModuleScope` contains all named items declared in the scope. -#[derive(Debug, PartialEq, Eq)] -pub(crate) struct ModuleScope { - entries: Vec, -} - -/// `Entry` is a single named declaration iside a module. -#[derive(Debug, PartialEq, Eq)] -pub(crate) struct Entry { - ptr: LocalSyntaxPtr, - kind: EntryKind, - name: SmolStr, -} - -#[derive(Debug, PartialEq, Eq)] -enum EntryKind { - Item, - Import, -} - -impl ModuleScope { - pub(super) fn new<'a>(items: impl Iterator>) -> ModuleScope { - let mut entries = Vec::new(); - for item in items { - let entry = match item { - ast::ModuleItem::StructDef(item) => Entry::new(item), - ast::ModuleItem::EnumDef(item) => Entry::new(item), - ast::ModuleItem::FnDef(item) => Entry::new(item), - ast::ModuleItem::ConstDef(item) => Entry::new(item), - ast::ModuleItem::StaticDef(item) => Entry::new(item), - ast::ModuleItem::TraitDef(item) => Entry::new(item), - ast::ModuleItem::TypeDef(item) => Entry::new(item), - ast::ModuleItem::Module(item) => Entry::new(item), - ast::ModuleItem::UseItem(item) => { - if let Some(tree) = item.use_tree() { - collect_imports(tree, &mut entries); - } - continue; - } - ast::ModuleItem::ExternCrateItem(_) | ast::ModuleItem::ImplItem(_) => continue, - }; - entries.extend(entry) - } - - ModuleScope { entries } - } - - pub fn entries(&self) -> &[Entry] { - self.entries.as_slice() - } -} - -impl Entry { - fn new<'a>(item: impl ast::NameOwner<'a>) -> Option { - let name = item.name()?; - Some(Entry { - name: name.text(), - ptr: LocalSyntaxPtr::new(name.syntax()), - kind: EntryKind::Item, - }) - } - fn new_import(path: ast::Path) -> Option { - let name_ref = path.segment()?.name_ref()?; - Some(Entry { - name: name_ref.text(), - ptr: LocalSyntaxPtr::new(name_ref.syntax()), - kind: EntryKind::Import, - }) - } - pub fn name(&self) -> &SmolStr { - &self.name - } - pub fn ptr(&self) -> LocalSyntaxPtr { - self.ptr - } -} - -fn collect_imports(tree: ast::UseTree, acc: &mut Vec) { - if let Some(use_tree_list) = tree.use_tree_list() { - return use_tree_list - .use_trees() - .for_each(|it| collect_imports(it, acc)); - } - if let Some(path) = tree.path() { - acc.extend(Entry::new_import(path)); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use ra_syntax::{ast::ModuleItemOwner, SourceFileNode}; - - fn do_check(code: &str, expected: &[&str]) { - let file = SourceFileNode::parse(&code); - let scope = ModuleScope::new(file.ast().items()); - let actual = scope.entries.iter().map(|it| it.name()).collect::>(); - assert_eq!(expected, actual.as_slice()); - } - - #[test] - fn test_module_scope() { - do_check( - " - struct Foo; - enum Bar {} - mod baz {} - fn quux() {} - use x::{ - y::z, - t, - }; - type T = (); - ", - &["Foo", "Bar", "baz", "quux", "z", "t", "T"], - ) - } -} -- cgit v1.2.3