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/idx.rs | 84 ---------------------------------- crates/libanalysis/src/lib.rs | 8 ++-- crates/libanalysis/src/symbol_index.rs | 56 +++++++++++++++-------- 3 files changed, 40 insertions(+), 108 deletions(-) delete mode 100644 crates/libanalysis/idx.rs (limited to 'crates/libanalysis') diff --git a/crates/libanalysis/idx.rs b/crates/libanalysis/idx.rs deleted file mode 100644 index 69a635aef..000000000 --- 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 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