diff --git a/crates/ide/src/ide/file_references.rs b/crates/ide/src/ide/file_references.rs index e6cdf9f..3998aef 100644 --- a/crates/ide/src/ide/file_references.rs +++ b/crates/ide/src/ide/file_references.rs @@ -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 { - let mut refs = db - .module_references(file) - .iter() - .copied() - .collect::>(); - refs.sort(); - refs -} +use crate::def::{Expr, Literal}; +use crate::{DefDatabase, FileId, NavigationTarget}; -pub(crate) fn file_referrers(db: &dyn DefDatabase, file: FileId) -> Vec { - db.module_referrers(file).into_vec() +pub(crate) fn file_referrers(db: &dyn DefDatabase, file: FileId) -> Vec { + 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 } diff --git a/crates/ide/src/ide/mod.rs b/crates/ide/src/ide/mod.rs index b074f1e..6497204 100644 --- a/crates/ide/src/ide/mod.rs +++ b/crates/ide/src/ide/mod.rs @@ -203,11 +203,7 @@ impl Analysis { //// Custom extensions //// - pub fn file_references(&self, file: FileId) -> Cancellable> { - self.with_db(|db| file_references::file_references(db, file)) - } - - pub fn file_referrers(&self, file: FileId) -> Cancellable> { + pub fn file_referrers(&self, file: FileId) -> Cancellable> { self.with_db(|db| file_references::file_referrers(db, file)) } } diff --git a/crates/nil/src/handler.rs b/crates/nil/src/handler.rs index fa6bcae..1f8c929 100644 --- a/crates/nil/src/handler.rs +++ b/crates/nil/src/handler.rs @@ -336,11 +336,13 @@ pub(crate) fn parent_module( params: TextDocumentPositionParams, ) -> Result>> { let (file, _) = convert::from_file(&snap.vfs(), ¶ms.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)) }