From a549da7e3ea66fd336de331c7c8d62b186051521 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 4 Mar 2020 12:05:14 +0100 Subject: Move SearchScope --- crates/ra_ide/src/references.rs | 2 +- crates/ra_ide/src/references/search_scope.rs | 144 -------------------------- crates/ra_ide_db/src/lib.rs | 1 + crates/ra_ide_db/src/search.rs | 147 +++++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 145 deletions(-) create mode 100644 crates/ra_ide_db/src/search.rs (limited to 'crates') diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index 95468d434..6fd46c52d 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs @@ -31,7 +31,7 @@ use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeI pub(crate) use self::rename::rename; -pub use self::search_scope::SearchScope; +pub use ra_ide_db::search::SearchScope; #[derive(Debug, Clone)] pub struct ReferenceSearchResult { diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs index d98c84d91..8b1378917 100644 --- a/crates/ra_ide/src/references/search_scope.rs +++ b/crates/ra_ide/src/references/search_scope.rs @@ -1,145 +1 @@ -//! Generally, `search_scope` returns files that might contain references for the element. -//! For `pub(crate)` things it's a crate, for `pub` things it's a crate and dependant crates. -//! In some cases, the location of the references is known to within a `TextRange`, -//! e.g. for things like local variables. -use std::mem; -use hir::{DefWithBody, HasSource, ModuleSource}; -use ra_db::{FileId, SourceDatabaseExt}; -use ra_prof::profile; -use ra_syntax::{AstNode, TextRange}; -use rustc_hash::FxHashMap; - -use ra_ide_db::RootDatabase; - -use super::Definition; - -pub struct SearchScope { - entries: FxHashMap>, -} - -impl SearchScope { - fn empty() -> SearchScope { - SearchScope { entries: FxHashMap::default() } - } - - pub(crate) fn for_def(def: &Definition, db: &RootDatabase) -> SearchScope { - let _p = profile("search_scope"); - let module = match def.module(db) { - Some(it) => it, - None => return SearchScope::empty(), - }; - let module_src = module.definition_source(db); - let file_id = module_src.file_id.original_file(db); - - if let Definition::Local(var) = def { - let range = match var.parent(db) { - DefWithBody::Function(f) => f.source(db).value.syntax().text_range(), - DefWithBody::Const(c) => c.source(db).value.syntax().text_range(), - DefWithBody::Static(s) => s.source(db).value.syntax().text_range(), - }; - let mut res = FxHashMap::default(); - res.insert(file_id, Some(range)); - return SearchScope::new(res); - } - - let vis = def.visibility(db).as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); - - if vis.as_str() == "pub(super)" { - if let Some(parent_module) = module.parent(db) { - let mut res = FxHashMap::default(); - let parent_src = parent_module.definition_source(db); - let file_id = parent_src.file_id.original_file(db); - - match parent_src.value { - ModuleSource::Module(m) => { - let range = Some(m.syntax().text_range()); - res.insert(file_id, range); - } - ModuleSource::SourceFile(_) => { - res.insert(file_id, None); - res.extend(parent_module.children(db).map(|m| { - let src = m.definition_source(db); - (src.file_id.original_file(db), None) - })); - } - } - return SearchScope::new(res); - } - } - - if vis.as_str() != "" { - let source_root_id = db.file_source_root(file_id); - let source_root = db.source_root(source_root_id); - let mut res = source_root.walk().map(|id| (id, None)).collect::>(); - - // FIXME: add "pub(in path)" - - if vis.as_str() == "pub(crate)" { - return SearchScope::new(res); - } - if vis.as_str() == "pub" { - let krate = module.krate(); - for rev_dep in krate.reverse_dependencies(db) { - let root_file = rev_dep.root_file(db); - let source_root_id = db.file_source_root(root_file); - let source_root = db.source_root(source_root_id); - res.extend(source_root.walk().map(|id| (id, None))); - } - return SearchScope::new(res); - } - } - - let mut res = FxHashMap::default(); - let range = match module_src.value { - ModuleSource::Module(m) => Some(m.syntax().text_range()), - ModuleSource::SourceFile(_) => None, - }; - res.insert(file_id, range); - SearchScope::new(res) - } - - fn new(entries: FxHashMap>) -> SearchScope { - SearchScope { entries } - } - pub fn single_file(file: FileId) -> SearchScope { - SearchScope::new(std::iter::once((file, None)).collect()) - } - pub(crate) fn intersection(&self, other: &SearchScope) -> SearchScope { - let (mut small, mut large) = (&self.entries, &other.entries); - if small.len() > large.len() { - mem::swap(&mut small, &mut large) - } - - let res = small - .iter() - .filter_map(|(file_id, r1)| { - let r2 = large.get(file_id)?; - let r = intersect_ranges(*r1, *r2)?; - Some((*file_id, r)) - }) - .collect(); - return SearchScope::new(res); - - fn intersect_ranges( - r1: Option, - r2: Option, - ) -> Option> { - match (r1, r2) { - (None, r) | (r, None) => Some(r), - (Some(r1), Some(r2)) => { - let r = r1.intersection(&r2)?; - Some(Some(r)) - } - } - } - } -} - -impl IntoIterator for SearchScope { - type Item = (FileId, Option); - type IntoIter = std::collections::hash_map::IntoIter>; - fn into_iter(self) -> Self::IntoIter { - self.entries.into_iter() - } -} diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs index aa312c140..79f48c9e3 100644 --- a/crates/ra_ide_db/src/lib.rs +++ b/crates/ra_ide_db/src/lib.rs @@ -9,6 +9,7 @@ pub mod feature_flags; pub mod symbol_index; pub mod change; pub mod defs; +pub mod search; pub mod imports_locator; mod wasm_shims; diff --git a/crates/ra_ide_db/src/search.rs b/crates/ra_ide_db/src/search.rs new file mode 100644 index 000000000..add63b870 --- /dev/null +++ b/crates/ra_ide_db/src/search.rs @@ -0,0 +1,147 @@ +//! Generally, `search_scope` returns files that might contain references for the element. +//! For `pub(crate)` things it's a crate, for `pub` things it's a crate and dependant crates. +//! In some cases, the location of the references is known to within a `TextRange`, +//! e.g. for things like local variables. +use std::mem; + +use hir::{DefWithBody, HasSource, ModuleSource}; +use ra_db::{FileId, SourceDatabaseExt}; +use ra_prof::profile; +use ra_syntax::{AstNode, TextRange}; +use rustc_hash::FxHashMap; + +use crate::{defs::Definition, RootDatabase}; + +pub struct SearchScope { + entries: FxHashMap>, +} + +impl SearchScope { + fn new(entries: FxHashMap>) -> SearchScope { + SearchScope { entries } + } + + pub fn empty() -> SearchScope { + SearchScope::new(FxHashMap::default()) + } + + pub fn single_file(file: FileId) -> SearchScope { + SearchScope::new(std::iter::once((file, None)).collect()) + } + + pub fn for_def(def: &Definition, db: &RootDatabase) -> SearchScope { + let _p = profile("search_scope"); + let module = match def.module(db) { + Some(it) => it, + None => return SearchScope::empty(), + }; + let module_src = module.definition_source(db); + let file_id = module_src.file_id.original_file(db); + + if let Definition::Local(var) = def { + let range = match var.parent(db) { + DefWithBody::Function(f) => f.source(db).value.syntax().text_range(), + DefWithBody::Const(c) => c.source(db).value.syntax().text_range(), + DefWithBody::Static(s) => s.source(db).value.syntax().text_range(), + }; + let mut res = FxHashMap::default(); + res.insert(file_id, Some(range)); + return SearchScope::new(res); + } + + let vis = def.visibility(db).as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); + + if vis.as_str() == "pub(super)" { + if let Some(parent_module) = module.parent(db) { + let mut res = FxHashMap::default(); + let parent_src = parent_module.definition_source(db); + let file_id = parent_src.file_id.original_file(db); + + match parent_src.value { + ModuleSource::Module(m) => { + let range = Some(m.syntax().text_range()); + res.insert(file_id, range); + } + ModuleSource::SourceFile(_) => { + res.insert(file_id, None); + res.extend(parent_module.children(db).map(|m| { + let src = m.definition_source(db); + (src.file_id.original_file(db), None) + })); + } + } + return SearchScope::new(res); + } + } + + if vis.as_str() != "" { + let source_root_id = db.file_source_root(file_id); + let source_root = db.source_root(source_root_id); + let mut res = source_root.walk().map(|id| (id, None)).collect::>(); + + // FIXME: add "pub(in path)" + + if vis.as_str() == "pub(crate)" { + return SearchScope::new(res); + } + if vis.as_str() == "pub" { + let krate = module.krate(); + for rev_dep in krate.reverse_dependencies(db) { + let root_file = rev_dep.root_file(db); + let source_root_id = db.file_source_root(root_file); + let source_root = db.source_root(source_root_id); + res.extend(source_root.walk().map(|id| (id, None))); + } + return SearchScope::new(res); + } + } + + let mut res = FxHashMap::default(); + let range = match module_src.value { + ModuleSource::Module(m) => Some(m.syntax().text_range()), + ModuleSource::SourceFile(_) => None, + }; + res.insert(file_id, range); + SearchScope::new(res) + } + + pub fn intersection(&self, other: &SearchScope) -> SearchScope { + let (mut small, mut large) = (&self.entries, &other.entries); + if small.len() > large.len() { + mem::swap(&mut small, &mut large) + } + + let res = small + .iter() + .filter_map(|(file_id, r1)| { + let r2 = large.get(file_id)?; + let r = intersect_ranges(*r1, *r2)?; + Some((*file_id, r)) + }) + .collect(); + + return SearchScope::new(res); + + fn intersect_ranges( + r1: Option, + r2: Option, + ) -> Option> { + match (r1, r2) { + (None, r) | (r, None) => Some(r), + (Some(r1), Some(r2)) => { + let r = r1.intersection(&r2)?; + Some(Some(r)) + } + } + } + } +} + +impl IntoIterator for SearchScope { + type Item = (FileId, Option); + type IntoIter = std::collections::hash_map::IntoIter>; + + fn into_iter(self) -> Self::IntoIter { + self.entries.into_iter() + } +} -- cgit v1.2.3