Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-db/src/search.rs')
-rw-r--r--crates/ide-db/src/search.rs89
1 files changed, 51 insertions, 38 deletions
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index e1cfe04898..05b32e2a85 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -6,16 +6,17 @@
use std::mem;
-use base_db::{salsa::Database, FileId, FileRange, SourceDatabase, SourceDatabaseExt};
+use base_db::{salsa::Database, SourceDatabase, SourceDatabaseExt};
use hir::{
- AsAssocItem, DefWithBody, DescendPreference, HasAttrs, HasSource, HirFileIdExt, InFile,
- InRealFile, ModuleSource, PathResolution, Semantics, Visibility,
+ sym, AsAssocItem, DefWithBody, DescendPreference, FileRange, HasAttrs, HasSource, HirFileIdExt,
+ InFile, InRealFile, ModuleSource, PathResolution, Semantics, Visibility,
};
use memchr::memmem::Finder;
-use nohash_hasher::IntMap;
use once_cell::unsync::Lazy;
use parser::SyntaxKind;
-use syntax::{ast, match_ast, AstNode, AstToken, SyntaxElement, TextRange, TextSize};
+use rustc_hash::FxHashMap;
+use span::EditionedFileId;
+use syntax::{ast, match_ast, AstNode, AstToken, SyntaxElement, TextRange, TextSize, ToSmolStr};
use triomphe::Arc;
use crate::{
@@ -26,7 +27,7 @@ use crate::{
#[derive(Debug, Default, Clone)]
pub struct UsageSearchResult {
- pub references: IntMap<FileId, Vec<FileReference>>,
+ pub references: FxHashMap<EditionedFileId, Vec<FileReference>>,
}
impl UsageSearchResult {
@@ -38,8 +39,8 @@ impl UsageSearchResult {
self.references.len()
}
- pub fn iter(&self) -> impl Iterator<Item = (&FileId, &[FileReference])> + '_ {
- self.references.iter().map(|(file_id, refs)| (file_id, &**refs))
+ pub fn iter(&self) -> impl Iterator<Item = (EditionedFileId, &[FileReference])> + '_ {
+ self.references.iter().map(|(&file_id, refs)| (file_id, &**refs))
}
pub fn file_ranges(&self) -> impl Iterator<Item = FileRange> + '_ {
@@ -50,8 +51,8 @@ impl UsageSearchResult {
}
impl IntoIterator for UsageSearchResult {
- type Item = (FileId, Vec<FileReference>);
- type IntoIter = <IntMap<FileId, Vec<FileReference>> as IntoIterator>::IntoIter;
+ type Item = (EditionedFileId, Vec<FileReference>);
+ type IntoIter = <FxHashMap<EditionedFileId, Vec<FileReference>> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.references.into_iter()
@@ -142,36 +143,40 @@ bitflags::bitflags! {
/// e.g. for things like local variables.
#[derive(Clone, Debug)]
pub struct SearchScope {
- entries: IntMap<FileId, Option<TextRange>>,
+ entries: FxHashMap<EditionedFileId, Option<TextRange>>,
}
impl SearchScope {
- fn new(entries: IntMap<FileId, Option<TextRange>>) -> SearchScope {
+ fn new(entries: FxHashMap<EditionedFileId, Option<TextRange>>) -> SearchScope {
SearchScope { entries }
}
/// Build a search scope spanning the entire crate graph of files.
fn crate_graph(db: &RootDatabase) -> SearchScope {
- let mut entries = IntMap::default();
+ let mut entries = FxHashMap::default();
let graph = db.crate_graph();
for krate in graph.iter() {
let root_file = graph[krate].root_file_id;
let source_root_id = db.file_source_root(root_file);
let source_root = db.source_root(source_root_id);
- entries.extend(source_root.iter().map(|id| (id, None)));
+ entries.extend(
+ source_root.iter().map(|id| (EditionedFileId::new(id, graph[krate].edition), None)),
+ );
}
SearchScope { entries }
}
/// Build a search scope spanning all the reverse dependencies of the given crate.
fn reverse_dependencies(db: &RootDatabase, of: hir::Crate) -> SearchScope {
- let mut entries = IntMap::default();
+ let mut entries = FxHashMap::default();
for rev_dep in of.transitive_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);
- entries.extend(source_root.iter().map(|id| (id, None)));
+ entries.extend(
+ source_root.iter().map(|id| (EditionedFileId::new(id, rev_dep.edition(db)), None)),
+ );
}
SearchScope { entries }
}
@@ -181,12 +186,17 @@ impl SearchScope {
let root_file = of.root_file(db);
let source_root_id = db.file_source_root(root_file);
let source_root = db.source_root(source_root_id);
- SearchScope { entries: source_root.iter().map(|id| (id, None)).collect() }
+ SearchScope {
+ entries: source_root
+ .iter()
+ .map(|id| (EditionedFileId::new(id, of.edition(db)), None))
+ .collect(),
+ }
}
/// Build a search scope spanning the given module and all its submodules.
pub fn module_and_children(db: &RootDatabase, module: hir::Module) -> SearchScope {
- let mut entries = IntMap::default();
+ let mut entries = FxHashMap::default();
let (file_id, range) = {
let InFile { file_id, value } = module.definition_source_range(db);
@@ -211,11 +221,11 @@ impl SearchScope {
/// Build an empty search scope.
pub fn empty() -> SearchScope {
- SearchScope::new(IntMap::default())
+ SearchScope::new(FxHashMap::default())
}
/// Build a empty search scope spanning the given file.
- pub fn single_file(file: FileId) -> SearchScope {
+ pub fn single_file(file: EditionedFileId) -> SearchScope {
SearchScope::new(std::iter::once((file, None)).collect())
}
@@ -225,7 +235,7 @@ impl SearchScope {
}
/// Build a empty search scope spanning the given files.
- pub fn files(files: &[FileId]) -> SearchScope {
+ pub fn files(files: &[EditionedFileId]) -> SearchScope {
SearchScope::new(files.iter().map(|f| (*f, None)).collect())
}
@@ -256,8 +266,8 @@ impl SearchScope {
}
impl IntoIterator for SearchScope {
- type Item = (FileId, Option<TextRange>);
- type IntoIter = std::collections::hash_map::IntoIter<FileId, Option<TextRange>>;
+ type Item = (EditionedFileId, Option<TextRange>);
+ type IntoIter = std::collections::hash_map::IntoIter<EditionedFileId, Option<TextRange>>;
fn into_iter(self) -> Self::IntoIter {
self.entries.into_iter()
@@ -333,7 +343,7 @@ impl Definition {
if let Definition::Macro(macro_def) = self {
return match macro_def.kind(db) {
hir::MacroKind::Declarative => {
- if macro_def.attrs(db).by_key("macro_export").exists() {
+ if macro_def.attrs(db).by_key(&sym::macro_export).exists() {
SearchScope::reverse_dependencies(db, module.krate())
} else {
SearchScope::krate(db, module.krate())
@@ -432,7 +442,7 @@ impl<'a> FindUsages<'a> {
res
}
- pub fn search(&self, sink: &mut dyn FnMut(FileId, FileReference) -> bool) {
+ pub fn search(&self, sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool) {
let _p = tracing::info_span!("FindUsages:search").entered();
let sema = self.sema;
@@ -456,7 +466,7 @@ impl<'a> FindUsages<'a> {
module
.krate()
.display_name(self.sema.db)
- .map(|crate_name| crate_name.crate_name().as_smol_str().clone())
+ .map(|crate_name| crate_name.crate_name().symbol().as_str().into())
}
_ => {
let self_kw_refs = || {
@@ -468,7 +478,10 @@ impl<'a> FindUsages<'a> {
};
// We need to unescape the name in case it is written without "r#" in earlier
// editions of Rust where it isn't a keyword.
- self.def.name(sema.db).or_else(self_kw_refs).map(|it| it.unescaped().to_smol_str())
+ self.def
+ .name(sema.db)
+ .or_else(self_kw_refs)
+ .map(|it| it.unescaped().display(sema.db).to_smolstr())
}
};
let name = match &name {
@@ -494,13 +507,13 @@ impl<'a> FindUsages<'a> {
})
}
- // for<'a> |scope: &'a SearchScope| -> impl Iterator<Item = (Arc<String>, FileId, TextRange)> + 'a { ... }
+ // for<'a> |scope: &'a SearchScope| -> impl Iterator<Item = (Arc<String>, EditionedFileId, TextRange)> + 'a { ... }
fn scope_files<'a>(
sema: &'a Semantics<'_, RootDatabase>,
scope: &'a SearchScope,
- ) -> impl Iterator<Item = (Arc<str>, FileId, TextRange)> + 'a {
+ ) -> impl Iterator<Item = (Arc<str>, EditionedFileId, TextRange)> + 'a {
scope.entries.iter().map(|(&file_id, &search_range)| {
- let text = sema.db.file_text(file_id);
+ let text = sema.db.file_text(file_id.file_id());
let search_range =
search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&*text)));
@@ -624,7 +637,7 @@ impl<'a> FindUsages<'a> {
return;
};
- let text = sema.db.file_text(file_id);
+ let text = sema.db.file_text(file_id.file_id());
let search_range =
search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(&*text)));
@@ -648,7 +661,7 @@ impl<'a> FindUsages<'a> {
&self,
self_ty: &hir::Type,
name_ref: &ast::NameRef,
- sink: &mut dyn FnMut(FileId, FileReference) -> bool,
+ sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
match NameRefClass::classify(self.sema, name_ref) {
Some(NameRefClass::Definition(Definition::SelfType(impl_)))
@@ -669,7 +682,7 @@ impl<'a> FindUsages<'a> {
fn found_self_module_name_ref(
&self,
name_ref: &ast::NameRef,
- sink: &mut dyn FnMut(FileId, FileReference) -> bool,
+ sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
match NameRefClass::classify(self.sema, name_ref) {
Some(NameRefClass::Definition(def @ Definition::Module(_))) if def == self.def => {
@@ -692,11 +705,11 @@ impl<'a> FindUsages<'a> {
fn found_format_args_ref(
&self,
- file_id: FileId,
+ file_id: EditionedFileId,
range: TextRange,
token: ast::String,
res: Option<PathResolution>,
- sink: &mut dyn FnMut(FileId, FileReference) -> bool,
+ sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
match res.map(Definition::from) {
Some(def) if def == self.def => {
@@ -714,7 +727,7 @@ impl<'a> FindUsages<'a> {
fn found_lifetime(
&self,
lifetime: &ast::Lifetime,
- sink: &mut dyn FnMut(FileId, FileReference) -> bool,
+ sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
match NameRefClass::classify_lifetime(self.sema, lifetime) {
Some(NameRefClass::Definition(def)) if def == self.def => {
@@ -733,7 +746,7 @@ impl<'a> FindUsages<'a> {
fn found_name_ref(
&self,
name_ref: &ast::NameRef,
- sink: &mut dyn FnMut(FileId, FileReference) -> bool,
+ sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
match NameRefClass::classify(self.sema, name_ref) {
Some(NameRefClass::Definition(def))
@@ -807,7 +820,7 @@ impl<'a> FindUsages<'a> {
fn found_name(
&self,
name: &ast::Name,
- sink: &mut dyn FnMut(FileId, FileReference) -> bool,
+ sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
match NameClass::classify(self.sema, name) {
Some(NameClass::PatFieldShorthand { local_def: _, field_ref })