diff options
Diffstat (limited to 'crates/libanalysis/src/lib.rs')
-rw-r--r-- | crates/libanalysis/src/lib.rs | 36 |
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 | ||
21 | use libsyntax2::ast; | 21 | use libsyntax2::{ |
22 | TextUnit, | ||
23 | ast::{self, AstNode}, | ||
24 | algo::{find_leaf_at_offset, ancestors}, | ||
25 | }; | ||
22 | use libeditor::{LineIndex, FileSymbol}; | 26 | use libeditor::{LineIndex, FileSymbol}; |
23 | 27 | ||
24 | use self::symbol_index::{FileSymbols}; | 28 | use self::symbol_index::FileSymbols; |
25 | pub use self::symbol_index::Query; | 29 | pub use self::symbol_index::Query; |
26 | 30 | ||
27 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | 31 | pub 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()), |