diff --git a/crates/libanalysis/idx.rs b/crates/libanalysis/idx.rs deleted file mode 100644 index 69a635aefe6..00000000000 --- a/crates/libanalysis/idx.rs +++ /dev/null @@ -1,84 +0,0 @@ -use std::path::PathBuf; - -use fst; -use fst::IntoStreamer; -use file; - -use fall_tree::{TextRange, NodeType}; -use indxr::{FileIndex, IndexableFileSet}; - -use editor::line_index::{LineCol, LineIndex}; -use editor::fst_subseq::FstSubSeq; -use editor::file_symbols::process_symbols; - -use syntax::{STRUCT_DEF, ENUM_DEF, TRAIT_DEF, TYPE_DEF}; - - -pub struct SymbolIndex { - index: FileIndex, -} - -impl SymbolIndex { - pub fn new(roots: Vec) -> SymbolIndex { - let file_set = IndexableFileSet::new(roots, "rs"); - let index = FileIndex::new(file_set, Box::new(|path| { - let text = file::get_text(path).ok()?; - Some(FileSymbols::new(text)) - })); - SymbolIndex { index } - } - - pub fn query(&self, query: &str) -> Vec<(PathBuf, Symbol)> { - let mut query = Query::new(query); - let mut result = Vec::new(); - self.process_query(&query, &mut result); - if result.is_empty() && !query.all_symbols { - query.all_symbols = true; - self.process_query(&query, &mut result); - } - result - } - - fn process_query(&self, query: &Query, acc: &mut Vec<(PathBuf, Symbol)>) { - self.index.process_files(&mut |file| { - query.process(&file.value, &mut |symbol| { - acc.push((file.path.clone(), symbol)) - }); - acc.len() > 512 - }); - } -} - -struct Query { - query: String, - all_symbols: bool, -} - -impl Query { - fn new(query: &str) -> Query { - let all_symbols = query.contains("#"); - let query: String = query.chars() - .filter(|&c| c != '#') - .flat_map(char::to_lowercase) - .collect(); - Query { query, all_symbols } - } - - fn process(&self, file: &FileSymbols, acc: &mut FnMut(Symbol)) { - fn is_type(ty: NodeType) -> bool { - match ty { - STRUCT_DEF | ENUM_DEF | TRAIT_DEF| TYPE_DEF => true, - _ => false, - } - } - - let a = FstSubSeq::new(&self.query); - for idx in file.map.search(a).into_stream().into_values() { - let idx = idx as usize; - let symbol = file.symbols[idx].clone(); - if self.all_symbols || is_type(symbol.ty) { - acc(symbol) - } - } - } -} diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index acaadb8a2e6..b2f4bdbb3a9 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs @@ -21,7 +21,8 @@ use libsyntax2::ast; use libeditor::{LineIndex, FileSymbol}; -use self::symbol_index::{FileSymbols, Query}; +use self::symbol_index::{FileSymbols}; +pub use self::symbol_index::Query; pub type Result = ::std::result::Result; @@ -89,14 +90,13 @@ pub fn file_line_index(&self, path: &Path) -> Result { Ok(index.clone()) } - pub fn world_symbols<'a>(&'a self, query: &str) -> impl Iterator + 'a + pub fn world_symbols<'a>(&'a self, query: Query) -> impl Iterator + 'a { - let q = Query::new(query); self.data.file_map.iter() .flat_map(move |(path, data)| { let path: &'a Path = path.as_path(); let symbols = data.symbols(path); - q.process(symbols).map(move |s| (path, s)) + query.process(symbols).map(move |s| (path, s)) }) } diff --git a/crates/libanalysis/src/symbol_index.rs b/crates/libanalysis/src/symbol_index.rs index 4d90aac0c65..88d5c499520 100644 --- a/crates/libanalysis/src/symbol_index.rs +++ b/crates/libanalysis/src/symbol_index.rs @@ -3,7 +3,7 @@ ast, SyntaxKind::{self, *}, }; -use fst::{self, IntoStreamer}; +use fst::{self, IntoStreamer, Streamer}; #[derive(Debug)] pub(crate) struct FileSymbols { @@ -30,19 +30,30 @@ pub(crate) fn new(file: &ast::File) -> FileSymbols { } } -pub(crate) struct Query { +pub struct Query { query: String, - all_symbols: bool, + lowercased: String, + only_types: bool, + exact: bool, } impl Query { - pub(crate) fn new(query: &str) -> Query { - let all_symbols = query.contains("#"); - let query: String = query.chars() - .filter(|&c| c != '#') - .flat_map(char::to_lowercase) - .collect(); - Query { query, all_symbols } + pub fn new(query: String) -> Query { + let lowercased = query.to_lowercase(); + Query { + query, + lowercased, + only_types: false, + exact: false, + } + } + + pub fn only_types(&mut self) { + self.only_types = true; + } + + pub fn exact(&mut self) { + self.exact = true; } pub(crate) fn process<'a>( @@ -55,16 +66,21 @@ fn is_type(kind: SyntaxKind) -> bool { _ => false, } } - let automaton = fst::automaton::Subsequence::new(&self.query); - let all_symbols = self.all_symbols; - file.map.search(automaton).into_stream() - .into_values() - .into_iter() - .map(move |idx| { - let idx = idx as usize; - &file.symbols[idx] - }) - .filter(move |s| all_symbols || is_type(s.kind)) + let automaton = fst::automaton::Subsequence::new(&self.lowercased); + let mut stream = file.map.search(automaton).into_stream(); + let mut res = Vec::new(); + while let Some((_, idx)) = stream.next() { + let idx = idx as usize; + let symbol = &file.symbols[idx]; + if self.only_types && !is_type(symbol.kind) { + continue; + } + if self.exact && symbol.name != self.query { + continue; + } + res.push(symbol) + } + res.into_iter() } } diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs index bd0e6825bca..f51909280ae 100644 --- a/crates/server/src/main_loop/handlers.rs +++ b/crates/server/src/main_loop/handlers.rs @@ -5,7 +5,7 @@ Command, TextDocumentIdentifier, WorkspaceEdit, SymbolInformation, Location, }; -use libanalysis::{World}; +use libanalysis::{World, Query}; use libeditor; use libsyntax2::TextUnit; use serde_json::{to_value, from_value}; @@ -100,7 +100,20 @@ pub fn handle_workspace_symbol( params: req::WorkspaceSymbolParams, ) -> Result>> { let mut acc = Vec::new(); - for (path, symbol) in world.world_symbols(¶ms.query).take(128) { + + let query = { + let all_symbols = params.query.contains("#"); + let query: String = params.query.chars() + .filter(|&c| c != '#') + .collect(); + let mut q = Query::new(query); + if !all_symbols { + q.only_types(); + } + q + }; + + for (path, symbol) in world.world_symbols(query).take(128) { let line_index = world.file_line_index(path)?; let info = SymbolInformation { diff --git a/crates/smol_str/src/lib.rs b/crates/smol_str/src/lib.rs index 41c3a39ef8a..79b179ef46f 100644 --- a/crates/smol_str/src/lib.rs +++ b/crates/smol_str/src/lib.rs @@ -49,6 +49,30 @@ fn eq(&self, other: &SmolStr) -> bool { } } +impl PartialEq for SmolStr { + fn eq(&self, other: &String) -> bool { + self.as_str() == other + } +} + +impl PartialEq for String { + fn eq(&self, other: &SmolStr) -> bool { + other == self + } +} + +impl<'a> PartialEq<&'a String> for SmolStr { + fn eq(&self, other: &&'a String) -> bool { + self == *other + } +} + +impl<'a> PartialEq for &'a String { + fn eq(&self, other: &SmolStr) -> bool { + *self == other + } +} + impl fmt::Debug for SmolStr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(self.as_str(), f)