aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libanalysis/src/lib.rs')
-rw-r--r--crates/libanalysis/src/lib.rs36
1 files changed, 32 insertions, 4 deletions
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs
index b2f4bdbb3..97b6dfca6 100644
--- a/crates/libanalysis/src/lib.rs
+++ b/crates/libanalysis/src/lib.rs
@@ -18,10 +18,14 @@ use std::{
18 path::{PathBuf, Path}, 18 path::{PathBuf, Path},
19}; 19};
20 20
21use libsyntax2::ast; 21use libsyntax2::{
22 TextUnit,
23 ast::{self, AstNode},
24 algo::{find_leaf_at_offset, ancestors},
25};
22use libeditor::{LineIndex, FileSymbol}; 26use libeditor::{LineIndex, FileSymbol};
23 27
24use self::symbol_index::{FileSymbols}; 28use self::symbol_index::FileSymbols;
25pub use self::symbol_index::Query; 29pub use self::symbol_index::Query;
26 30
27pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 31pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
@@ -90,8 +94,7 @@ impl World {
90 Ok(index.clone()) 94 Ok(index.clone())
91 } 95 }
92 96
93 pub fn world_symbols<'a>(&'a self, query: Query) -> impl Iterator<Item=(&'a Path, &'a FileSymbol)> + 'a 97 pub fn world_symbols<'a>(&'a self, query: Query) -> impl Iterator<Item=(&'a Path, &'a FileSymbol)> + 'a {
94 {
95 self.data.file_map.iter() 98 self.data.file_map.iter()
96 .flat_map(move |(path, data)| { 99 .flat_map(move |(path, data)| {
97 let path: &'a Path = path.as_path(); 100 let path: &'a Path = path.as_path();
@@ -100,6 +103,31 @@ impl World {
100 }) 103 })
101 } 104 }
102 105
106 pub fn approximately_resolve_symbol<'a>(
107 &'a self,
108 path: &Path,
109 offset: TextUnit,
110 ) -> Result<Vec<(&'a Path, &'a FileSymbol)>> {
111 let file = self.file_syntax(path)?;
112 let syntax = file.syntax();
113 let syntax = syntax.as_ref();
114 let name_ref =
115 find_leaf_at_offset(syntax, offset)
116 .left_biased()
117 .into_iter()
118 .flat_map(|node| ancestors(node))
119 .flat_map(ast::NameRef::cast)
120 .next();
121 let name = match name_ref {
122 None => return Ok(vec![]),
123 Some(name_ref) => name_ref.text(),
124 };
125
126 let mut query = Query::new(name.to_string());
127 query.exact();
128 Ok(self.world_symbols(query).take(4).collect())
129 }
130
103 fn file_data(&self, path: &Path) -> Result<Arc<FileData>> { 131 fn file_data(&self, path: &Path) -> Result<Arc<FileData>> {
104 match self.data.file_map.get(path) { 132 match self.data.file_map.get(path) {
105 Some(data) => Ok(data.clone()), 133 Some(data) => Ok(data.clone()),