diff --git a/crates/ide/src/ide/file_references.rs b/crates/ide/src/ide/file_references.rs new file mode 100644 index 0000000..e6cdf9f --- /dev/null +++ b/crates/ide/src/ide/file_references.rs @@ -0,0 +1,15 @@ +use crate::{DefDatabase, FileId}; + +pub(crate) fn file_references(db: &dyn DefDatabase, file: FileId) -> Vec { + let mut refs = db + .module_references(file) + .iter() + .copied() + .collect::>(); + refs.sort(); + refs +} + +pub(crate) fn file_referrers(db: &dyn DefDatabase, file: FileId) -> Vec { + db.module_referrers(file).into_vec() +} diff --git a/crates/ide/src/ide/mod.rs b/crates/ide/src/ide/mod.rs index d170e9f..b074f1e 100644 --- a/crates/ide/src/ide/mod.rs +++ b/crates/ide/src/ide/mod.rs @@ -2,6 +2,7 @@ mod assists; mod completion; mod diagnostics; mod expand_selection; +mod file_references; mod goto_definition; mod highlight_related; mod hover; @@ -134,6 +135,8 @@ impl Analysis { Cancelled::catch(|| f(&self.db)) } + //// LSP standard //// + pub fn expand_selection(&self, frange: FileRange) -> Cancellable>> { self.with_db(|db| expand_selection::expand_selection(db, frange)) } @@ -197,4 +200,14 @@ impl Analysis { pub fn highlight_related(&self, fpos: FilePos) -> Cancellable> { self.with_db(|db| highlight_related::highlight_related(db, fpos).unwrap_or_default()) } + + //// 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> { + 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 d3c973d..43af97e 100644 --- a/crates/nil/src/handler.rs +++ b/crates/nil/src/handler.rs @@ -330,3 +330,17 @@ pub(crate) fn document_highlight( let ret = convert::to_document_highlight(&line_map, &ret); Ok(Some(ret)) } + +pub(crate) fn parent_module( + snap: StateSnapshot, + params: TextDocumentPositionParams, +) -> Result> { + let (file, _) = convert::from_file(&snap.vfs(), ¶ms.text_document)?; + let files = snap.analysis.file_referrers(file)?; + let vfs = snap.vfs(); + let locs = files + .into_iter() + .map(|file| convert::to_location(&vfs, FileRange::new(file, TextRange::default()))) + .collect(); + Ok(Some(GotoDefinitionResponse::Array(locs))) +} diff --git a/crates/nil/src/lib.rs b/crates/nil/src/lib.rs index 747831b..3af7a02 100644 --- a/crates/nil/src/lib.rs +++ b/crates/nil/src/lib.rs @@ -2,6 +2,7 @@ mod capabilities; mod config; mod convert; mod handler; +mod lsp_ext; mod semantic_tokens; mod server; mod vfs; diff --git a/crates/nil/src/lsp_ext.rs b/crates/nil/src/lsp_ext.rs new file mode 100644 index 0000000..08cca0b --- /dev/null +++ b/crates/nil/src/lsp_ext.rs @@ -0,0 +1,10 @@ +use lsp_types::request::Request; + +/// https://github.com/microsoft/language-server-protocol/issues/1002 +pub enum ParentModule {} + +impl Request for ParentModule { + type Params = lsp_types::TextDocumentPositionParams; + type Result = Option; + const METHOD: &'static str = "experimental/parentModule"; +} diff --git a/crates/nil/src/server.rs b/crates/nil/src/server.rs index 715ffd8..a16d420 100644 --- a/crates/nil/src/server.rs +++ b/crates/nil/src/server.rs @@ -1,5 +1,5 @@ use crate::config::{Config, CONFIG_KEY}; -use crate::{convert, handler, LspError, UrlExt, Vfs, MAX_FILE_LEN}; +use crate::{convert, handler, lsp_ext, LspError, UrlExt, Vfs, MAX_FILE_LEN}; use anyhow::{anyhow, bail, Context, Result}; use crossbeam_channel::{Receiver, Sender}; use ide::{Analysis, AnalysisHost, Cancelled, FlakeInfo, VfsPath}; @@ -273,6 +273,7 @@ impl Server { .on::(handler::document_links) .on::(handler::code_action) .on::(handler::document_highlight) + .on::(handler::parent_module) .finish(); }