From 5b0e347f89be317d21fd894c0ccf4abee5645429 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 27 Nov 2018 16:30:02 +0300 Subject: Make resolve_path cancelable --- crates/ra_analysis/src/completion/reference_completion.rs | 2 +- crates/ra_analysis/src/descriptors/module/mod.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index 1faa70a18..41df881b3 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs @@ -157,7 +157,7 @@ fn complete_path( return Ok(()); } path.segments.pop(); - let target_module = match module.resolve_path(path) { + let target_module = match module.resolve_path(path)? { None => return Ok(()), Some(it) => it, }; diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index a6eaec178..f5238e239 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -133,7 +133,15 @@ impl ModuleDescriptor { Ok(res) } - pub(crate) fn resolve_path(&self, path: Path) -> Option { + pub(crate) fn resolve_path(&self, path: Path) -> Cancelable> { + let res = match self.do_resolve_path(path) { + None => return Ok(None), + Some(it) => it, + }; + Ok(Some(res)) + } + + fn do_resolve_path(&self, path: Path) -> Option { let mut curr = match path.kind { PathKind::Crate => self.crate_root(), PathKind::Self_ | PathKind::Plain => self.clone(), -- cgit v1.2.3 From 68f66e0f446a2bd2385cfd236856f2a73bd58a3d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 27 Nov 2018 16:32:36 +0300 Subject: add db to resolve_path --- crates/ra_analysis/src/completion/reference_completion.rs | 2 +- crates/ra_analysis/src/descriptors/module/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index 41df881b3..924d2440f 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs @@ -157,7 +157,7 @@ fn complete_path( return Ok(()); } path.segments.pop(); - let target_module = match module.resolve_path(path)? { + let target_module = match module.resolve_path(db, path)? { None => return Ok(()), Some(it) => it, }; diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index f5238e239..6890d8b09 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -133,7 +133,7 @@ impl ModuleDescriptor { Ok(res) } - pub(crate) fn resolve_path(&self, path: Path) -> Cancelable> { + pub(crate) fn resolve_path(&self, db: &impl DescriptorDatabase, path: Path) -> Cancelable> { let res = match self.do_resolve_path(path) { None => return Ok(None), Some(it) => it, -- cgit v1.2.3 From f4860870dae309f5287a287de0aa3a1a1b1de36b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 27 Nov 2018 16:55:56 +0300 Subject: scope-based resolve path --- .../src/completion/reference_completion.rs | 16 +++----- crates/ra_analysis/src/descriptors/module/mod.rs | 47 +++++++++++++++++----- .../ra_analysis/src/descriptors/module/nameres.rs | 11 ++++- 3 files changed, 53 insertions(+), 21 deletions(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index 924d2440f..a0af59178 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs @@ -42,8 +42,7 @@ pub(super) fn completions( let module_scope = module.scope(db)?; acc.extend( module_scope - .items - .iter() + .entries() .filter(|(_name, res)| { // Don't expose this item match res.import { @@ -162,14 +161,11 @@ fn complete_path( Some(it) => it, }; let module_scope = target_module.scope(db)?; - let completions = module_scope - .items - .iter() - .map(|(name, _res)| CompletionItem { - label: name.to_string(), - lookup: None, - snippet: None, - }); + let completions = module_scope.entries().map(|(name, _res)| CompletionItem { + label: name.to_string(), + lookup: None, + snippet: None, + }); acc.extend(completions); Ok(()) } diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 6890d8b09..51bc84bf1 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -17,6 +17,7 @@ use crate::{ descriptors::{Path, PathKind, DescriptorDatabase}, input::SourceRootId, arena::{Arena, Id}, + loc2id::DefLoc, }; pub(crate) use self::nameres::ModuleScope; @@ -76,6 +77,20 @@ impl ModuleDescriptor { Ok(res) } + fn new( + db: &impl DescriptorDatabase, + source_root_id: SourceRootId, + module_id: ModuleId, + ) -> Cancelable { + let module_tree = db._module_tree(source_root_id)?; + let res = ModuleDescriptor { + tree: module_tree, + source_root_id, + module_id, + }; + Ok(res) + } + /// Returns `mod foo;` or `mod foo {}` node whihc declared this module. /// Returns `None` for the root module pub fn parent_link_source( @@ -133,25 +148,37 @@ impl ModuleDescriptor { Ok(res) } - pub(crate) fn resolve_path(&self, db: &impl DescriptorDatabase, path: Path) -> Cancelable> { - let res = match self.do_resolve_path(path) { - None => return Ok(None), - Some(it) => it, + pub(crate) fn resolve_path( + &self, + db: &impl DescriptorDatabase, + path: Path, + ) -> Cancelable> { + macro_rules! ctry { + ($expr:expr) => { + match $expr { + None => return Ok(None), + Some(it) => it, + } + }; }; - Ok(Some(res)) - } - fn do_resolve_path(&self, path: Path) -> Option { let mut curr = match path.kind { PathKind::Crate => self.crate_root(), PathKind::Self_ | PathKind::Plain => self.clone(), - PathKind::Super => self.parent()?, + PathKind::Super => ctry!(self.parent()), }; + let segments = path.segments; for name in segments { - curr = curr.child(&name)?; + let scope = curr.scope(db)?; + let def_id = ctry!(ctry!(scope.get(&name)).def_id); + curr = match db.id_maps().def_loc(def_id) { + DefLoc::Module { id, source_root } => ModuleDescriptor::new(db, source_root, id)?, + _ => return Ok(None), + }; } - Some(curr) + + Ok(Some(curr)) } 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 d347a69b0..d2964f67f 100644 --- a/crates/ra_analysis/src/descriptors/module/nameres.rs +++ b/crates/ra_analysis/src/descriptors/module/nameres.rs @@ -103,7 +103,16 @@ pub(crate) struct ItemMap { #[derive(Debug, Default, PartialEq, Eq, Clone)] pub(crate) struct ModuleScope { - pub(crate) items: FxHashMap, + items: FxHashMap, +} + +impl ModuleScope { + pub(crate) fn entries<'a>(&'a self) -> impl Iterator + 'a { + self.items.iter() + } + pub(crate) fn get(&self, name: &SmolStr) -> Option<&Resolution> { + self.items.get(name) + } } /// A set of items and imports declared inside a module, without relation to -- cgit v1.2.3 From aa7fd563a4b8817223ac50fa22cd946ce354f47d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 27 Nov 2018 18:45:16 +0300 Subject: use ctry --- crates/ra_analysis/src/completion/mod.rs | 5 +---- crates/ra_analysis/src/descriptors/module/mod.rs | 11 +---------- crates/ra_analysis/src/imp.rs | 10 ++-------- crates/ra_analysis/src/lib.rs | 9 +++++++++ 4 files changed, 13 insertions(+), 22 deletions(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/completion/mod.rs b/crates/ra_analysis/src/completion/mod.rs index c7717ab61..5ef278127 100644 --- a/crates/ra_analysis/src/completion/mod.rs +++ b/crates/ra_analysis/src/completion/mod.rs @@ -38,10 +38,7 @@ pub(crate) fn completions( original_file.reparse(&edit) }; - let module = match ModuleDescriptor::guess_from_position(db, position)? { - None => return Ok(None), - Some(it) => it, - }; + let module = ctry!(ModuleDescriptor::guess_from_position(db, position)?); let mut res = Vec::new(); let mut has_completions = false; diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 51bc84bf1..764e19ce0 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -17,7 +17,7 @@ use crate::{ descriptors::{Path, PathKind, DescriptorDatabase}, input::SourceRootId, arena::{Arena, Id}, - loc2id::DefLoc, + loc2id::{DefLoc, DefId}, }; pub(crate) use self::nameres::ModuleScope; @@ -153,15 +153,6 @@ impl ModuleDescriptor { db: &impl DescriptorDatabase, path: Path, ) -> Cancelable> { - macro_rules! ctry { - ($expr:expr) => { - match $expr { - None => return Ok(None), - Some(it) => it, - } - }; - }; - let mut curr = match path.kind { PathKind::Crate => self.crate_root(), PathKind::Self_ | PathKind::Plain => self.clone(), diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index ad6b52371..8a41b3152 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -450,14 +450,8 @@ impl AnalysisImpl { let syntax = file.syntax(); // Find the calling expression and it's NameRef - let calling_node = match FnCallNode::with_node(syntax, position.offset) { - Some(node) => node, - None => return Ok(None), - }; - let name_ref = match calling_node.name_ref() { - Some(name) => name, - None => return Ok(None), - }; + let calling_node = ctry!(FnCallNode::with_node(syntax, position.offset)); + let name_ref = ctry!(calling_node.name_ref()); // Resolve the function's NameRef (NOTE: this isn't entirely accurate). let file_symbols = self.index_resolve(name_ref)?; diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index cedbd1fc8..0fbfd8a40 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -9,6 +9,15 @@ extern crate relative_path; extern crate rustc_hash; extern crate salsa; +macro_rules! ctry { + ($expr:expr) => { + match $expr { + None => return Ok(None), + Some(it) => it, + } + }; +} + mod arena; mod db; mod loc2id; -- cgit v1.2.3 From 192e2bbb0e5c772d43ec61d36de56a0f7062610e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 27 Nov 2018 19:56:03 +0300 Subject: resolve_path works with DefIds --- .../src/completion/reference_completion.rs | 7 +++++- crates/ra_analysis/src/descriptors/mod.rs | 26 ++++++++++++++++++++-- crates/ra_analysis/src/descriptors/module/mod.rs | 24 +++++++++++++------- 3 files changed, 46 insertions(+), 11 deletions(-) (limited to 'crates/ra_analysis') diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index a0af59178..858b52e76 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs @@ -13,6 +13,7 @@ use crate::{ descriptors::{ module::{ModuleDescriptor}, function::FnScopes, + Def, Path, }, Cancelable @@ -156,10 +157,14 @@ fn complete_path( return Ok(()); } path.segments.pop(); - let target_module = match module.resolve_path(db, path)? { + let def_id = match module.resolve_path(db, path)? { None => return Ok(()), Some(it) => it, }; + let target_module = match def_id.resolve(db)? { + Def::Module(it) => it, + Def::Item => return Ok(()), + }; let module_scope = target_module.scope(db)?; let completions = module_scope.entries().map(|(name, _res)| CompletionItem { label: name.to_string(), diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index 98094d9ee..7a1bcf447 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs @@ -13,9 +13,12 @@ use crate::{ FileId, db::SyntaxDatabase, descriptors::function::{resolve_local_name, FnId, FnScopes}, - descriptors::module::{ModuleId, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems, FileItems}}, + descriptors::module::{ + ModuleId, ModuleTree, ModuleSource, ModuleDescriptor, + nameres::{ItemMap, InputModuleItems, FileItems} + }, input::SourceRootId, - loc2id::IdDatabase, + loc2id::{IdDatabase, DefId, DefLoc}, syntax_ptr::LocalSyntaxPtr, Cancelable, }; @@ -67,6 +70,25 @@ salsa::query_group! { } } +pub(crate) enum Def { + Module(ModuleDescriptor), + Item, +} + +impl DefId { + pub(crate) fn resolve(self, db: &impl DescriptorDatabase) -> Cancelable { + let loc = db.id_maps().def_loc(self); + let res = match loc { + DefLoc::Module { id, source_root } => { + let descr = ModuleDescriptor::new(db, source_root, id)?; + Def::Module(descr) + } + DefLoc::Item { .. } => Def::Item, + }; + Ok(res) + } +} + #[derive(Debug)] pub struct ReferenceDescriptor { pub range: TextRange, diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 764e19ce0..78911d5d9 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs @@ -77,7 +77,7 @@ impl ModuleDescriptor { Ok(res) } - fn new( + pub(super) fn new( db: &impl DescriptorDatabase, source_root_id: SourceRootId, module_id: ModuleId, @@ -132,6 +132,14 @@ impl ModuleDescriptor { Some(link.name(&self.tree)) } + pub fn def_id(&self, db: &impl DescriptorDatabase) -> DefId { + let def_loc = DefLoc::Module { + id: self.module_id, + source_root: self.source_root_id, + }; + db.id_maps().def_id(def_loc) + } + /// Finds a child module with the specified name. pub fn child(&self, name: &str) -> Option { let child_id = self.module_id.child(&self.tree, name)?; @@ -152,23 +160,23 @@ impl ModuleDescriptor { &self, db: &impl DescriptorDatabase, path: Path, - ) -> Cancelable> { + ) -> Cancelable> { let mut curr = match path.kind { PathKind::Crate => self.crate_root(), PathKind::Self_ | PathKind::Plain => self.clone(), PathKind::Super => ctry!(self.parent()), - }; + } + .def_id(db); let segments = path.segments; - for name in segments { - let scope = curr.scope(db)?; - let def_id = ctry!(ctry!(scope.get(&name)).def_id); - curr = match db.id_maps().def_loc(def_id) { + for name in segments.iter() { + let module = match db.id_maps().def_loc(curr) { DefLoc::Module { id, source_root } => ModuleDescriptor::new(db, source_root, id)?, _ => return Ok(None), }; + let scope = module.scope(db)?; + curr = ctry!(ctry!(scope.get(&name)).def_id); } - Ok(Some(curr)) } -- cgit v1.2.3