Precise file referrers

This commit is contained in:
oxalica 2023-03-02 05:46:43 +08:00
parent 3653128f18
commit 31fee4db73
3 changed files with 37 additions and 20 deletions

View file

@ -1,15 +1,34 @@
use crate::{DefDatabase, FileId};
use nix_interop::DEFAULT_IMPORT_FILE;
pub(crate) fn file_references(db: &dyn DefDatabase, file: FileId) -> Vec<FileId> {
let mut refs = db
.module_references(file)
.iter()
.copied()
.collect::<Vec<_>>();
refs.sort();
refs
}
use crate::def::{Expr, Literal};
use crate::{DefDatabase, FileId, NavigationTarget};
pub(crate) fn file_referrers(db: &dyn DefDatabase, file: FileId) -> Vec<FileId> {
db.module_referrers(file).into_vec()
pub(crate) fn file_referrers(db: &dyn DefDatabase, file: FileId) -> Vec<NavigationTarget> {
let source_root = db.source_root(db.file_source_root(file));
let mut targets = Vec::new();
for parent in db.module_referrers(file) {
let module = db.module(parent);
let source_map = db.source_map(parent);
targets.extend(module.exprs().filter_map(|(expr_id, kind)| {
// FIXME: This code dups with `module_references_query`.
// We should rework the resolution of def::Path.
let &Expr::Literal(Literal::Path(path)) = kind else { return None };
let mut vpath = path.resolve(db)?;
let target_file = source_root.file_for_path(&vpath).or_else(|| {
vpath.push(DEFAULT_IMPORT_FILE)?;
source_root.file_for_path(&vpath)
})?;
if target_file != file {
return None;
}
let range = source_map.node_for_expr(expr_id)?.text_range();
Some(NavigationTarget {
file_id: parent,
full_range: range,
focus_range: range,
})
}));
}
targets
}

View file

@ -203,11 +203,7 @@ impl Analysis {
//// Custom extensions ////
pub fn file_references(&self, file: FileId) -> Cancellable<Vec<FileId>> {
self.with_db(|db| file_references::file_references(db, file))
}
pub fn file_referrers(&self, file: FileId) -> Cancellable<Vec<FileId>> {
pub fn file_referrers(&self, file: FileId) -> Cancellable<Vec<NavigationTarget>> {
self.with_db(|db| file_references::file_referrers(db, file))
}
}

View file

@ -336,11 +336,13 @@ pub(crate) fn parent_module(
params: TextDocumentPositionParams,
) -> Result<Option<Vec<Location>>> {
let (file, _) = convert::from_file(&snap.vfs(), &params.text_document)?;
let files = snap.analysis.file_referrers(file)?;
let targets = snap.analysis.file_referrers(file)?;
let vfs = snap.vfs();
let locs = files
let locs = targets
.into_iter()
.map(|file| convert::to_location(&vfs, FileRange::new(file, TextRange::default())))
.map(|target| {
convert::to_location(&vfs, FileRange::new(target.file_id, target.focus_range))
})
.collect();
Ok(Some(locs))
}