From 7fc91f41d8bd948cef3085d7c0d0ec92d1b2bc53 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 13 Aug 2018 16:07:05 +0300 Subject: Generalize query --- crates/libanalysis/src/lib.rs | 8 ++--- crates/libanalysis/src/symbol_index.rs | 56 ++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 24 deletions(-) (limited to 'crates/libanalysis/src') diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index acaadb8a2..b2f4bdbb3 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs @@ -21,7 +21,8 @@ use std::{ 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 @@ impl World { 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 4d90aac0c..88d5c4995 100644 --- a/crates/libanalysis/src/symbol_index.rs +++ b/crates/libanalysis/src/symbol_index.rs @@ -3,7 +3,7 @@ use libsyntax2::{ ast, SyntaxKind::{self, *}, }; -use fst::{self, IntoStreamer}; +use fst::{self, IntoStreamer, Streamer}; #[derive(Debug)] pub(crate) struct FileSymbols { @@ -30,19 +30,30 @@ impl 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 @@ impl Query { _ => 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() } } -- cgit v1.2.3