2018-08-13 15:10:20 +03:00
|
|
|
use libeditor::{FileSymbol, file_symbols};
|
|
|
|
|
use libsyntax2::{
|
|
|
|
|
ast,
|
|
|
|
|
SyntaxKind::{self, *},
|
|
|
|
|
};
|
|
|
|
|
use fst::{self, IntoStreamer};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub(crate) struct FileSymbols {
|
|
|
|
|
symbols: Vec<FileSymbol>,
|
|
|
|
|
map: fst::Map,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl FileSymbols {
|
|
|
|
|
pub(crate) fn new(file: &ast::File) -> FileSymbols {
|
|
|
|
|
let mut symbols = file_symbols(file)
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|s| (s.name.as_str().to_lowercase(), s))
|
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
|
|
symbols.sort_by(|s1, s2| s1.0.cmp(&s2.0));
|
|
|
|
|
symbols.dedup_by(|s1, s2| s1.0 == s2.0);
|
|
|
|
|
let (names, symbols): (Vec<String>, Vec<FileSymbol>) =
|
|
|
|
|
symbols.into_iter().unzip();
|
|
|
|
|
|
|
|
|
|
let map = fst::Map::from_iter(
|
|
|
|
|
names.into_iter().zip(0u64..)
|
|
|
|
|
).unwrap();
|
|
|
|
|
FileSymbols { symbols, map }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(crate) struct Query {
|
|
|
|
|
query: String,
|
|
|
|
|
all_symbols: 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 }
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-13 15:35:53 +03:00
|
|
|
pub(crate) fn process<'a>(
|
2018-08-13 15:10:20 +03:00
|
|
|
&self,
|
2018-08-13 15:35:53 +03:00
|
|
|
file: &'a FileSymbols,
|
|
|
|
|
) -> impl Iterator<Item=&'a FileSymbol> + 'a {
|
2018-08-13 15:10:20 +03:00
|
|
|
fn is_type(kind: SyntaxKind) -> bool {
|
|
|
|
|
match kind {
|
|
|
|
|
STRUCT | ENUM | TRAIT | TYPE_ITEM => true,
|
|
|
|
|
_ => false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let automaton = fst::automaton::Subsequence::new(&self.query);
|
2018-08-13 15:35:53 +03:00
|
|
|
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))
|
2018-08-13 15:10:20 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|