From 081c16c77642a5c86ed72c5fbd11deccc2edd5d5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Aug 2018 15:37:17 +0300 Subject: initial mod resolve --- crates/libanalysis/src/lib.rs | 56 +++++++++++++++++++++++++--------- crates/libanalysis/src/symbol_index.rs | 8 ++--- 2 files changed, 45 insertions(+), 19 deletions(-) (limited to 'crates/libanalysis') diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index 9429f8f55..19b64fece 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs @@ -16,7 +16,7 @@ use rayon::prelude::*; use std::{ fmt, - path::Path, + path::{Path, PathBuf}, sync::{ Arc, atomic::{AtomicUsize, Ordering::SeqCst}, @@ -26,8 +26,9 @@ use std::{ }; use libsyntax2::{ - TextUnit, - ast::{self, AstNode}, + TextUnit, TextRange, SyntaxRoot, + ast::{self, AstNode, NameOwner}, + SyntaxKind::*, }; use libeditor::{LineIndex, FileSymbol, find_node}; @@ -119,33 +120,58 @@ impl World { Ok(index.clone()) } - pub fn world_symbols<'a>(&'a self, mut query: Query) -> impl Iterator + 'a { + pub fn world_symbols(&self, mut query: Query) -> Vec<(FileId, FileSymbol)> { self.reindex(); self.data.file_map.iter() .flat_map(move |(id, data)| { let symbols = data.symbols(); query.process(symbols).into_iter().map(move |s| (*id, s)) }) + .collect() } - pub fn approximately_resolve_symbol<'a>( - &'a self, + pub fn approximately_resolve_symbol( + &self, id: FileId, offset: TextUnit, - ) -> Result> { + ) -> Result> { let file = self.file_syntax(id)?; - let syntax = file.syntax(); - let syntax = syntax.as_ref(); - let name_ref = find_node::>(syntax, offset); - let name = match name_ref { - None => return Ok(vec![]), - Some(name_ref) => name_ref.text(), - }; + let syntax = file.syntax_ref(); + if let Some(name_ref) = find_node::>(syntax, offset) { + return Ok(self.index_resolve(name_ref)); + } + if let Some(name) = find_node::>(syntax, offset) { + if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { + if module.has_semi() { + return Ok(self.resolve_module(id, module)); + } + } + } + Ok(vec![]) + } + fn index_resolve(&self, name_ref: ast::NameRef<&SyntaxRoot>) -> Vec<(FileId, FileSymbol)> { + let name = name_ref.text(); let mut query = Query::new(name.to_string()); query.exact(); query.limit(4); - Ok(self.world_symbols(query).collect()) + self.world_symbols(query) + } + + fn resolve_module(&self, id: FileId, module: ast::Module<&SyntaxRoot>) -> Vec<(FileId, FileSymbol)> { + let name = match module.name() { + Some(name) => name.text(), + None => return Vec::new(), + }; + let id = match self.resolve_relative_path(id, &PathBuf::from(format!("../{}.rs", name))) { + Some(id) => id, + None => return Vec::new(), + }; + vec![(id, FileSymbol { + name: name.clone(), + node_range: TextRange::offset_len(0.into(), 0.into()), + kind: MODULE, + })] } fn resolve_relative_path(&self, id: FileId, path: &Path) -> Option { diff --git a/crates/libanalysis/src/symbol_index.rs b/crates/libanalysis/src/symbol_index.rs index 35141cfdc..3c3252956 100644 --- a/crates/libanalysis/src/symbol_index.rs +++ b/crates/libanalysis/src/symbol_index.rs @@ -62,10 +62,10 @@ impl Query { self.limit = limit } - pub(crate) fn process<'a>( + pub(crate) fn process( &mut self, - file: &'a FileSymbols, - ) -> Vec<&'a FileSymbol> { + file: &FileSymbols, + ) -> Vec { fn is_type(kind: SyntaxKind) -> bool { match kind { STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_DEF => true, @@ -87,7 +87,7 @@ impl Query { if self.exact && symbol.name != self.query { continue; } - res.push(symbol); + res.push(symbol.clone()); self.limit -= 1; } res -- cgit v1.2.3