diff options
author | Aleksey Kladov <[email protected]> | 2018-08-17 13:37:17 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-17 13:37:17 +0100 |
commit | 081c16c77642a5c86ed72c5fbd11deccc2edd5d5 (patch) | |
tree | 90ddf4f92954fcb00f4c20a46968932c5f0bbdea /crates/libanalysis/src | |
parent | 55e87e0b742b46d40b1a5ef1598804e48e45f0e0 (diff) |
initial mod resolve
Diffstat (limited to 'crates/libanalysis/src')
-rw-r--r-- | crates/libanalysis/src/lib.rs | 56 | ||||
-rw-r--r-- | crates/libanalysis/src/symbol_index.rs | 8 |
2 files changed, 45 insertions, 19 deletions
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::*; | |||
16 | 16 | ||
17 | use std::{ | 17 | use std::{ |
18 | fmt, | 18 | fmt, |
19 | path::Path, | 19 | path::{Path, PathBuf}, |
20 | sync::{ | 20 | sync::{ |
21 | Arc, | 21 | Arc, |
22 | atomic::{AtomicUsize, Ordering::SeqCst}, | 22 | atomic::{AtomicUsize, Ordering::SeqCst}, |
@@ -26,8 +26,9 @@ use std::{ | |||
26 | }; | 26 | }; |
27 | 27 | ||
28 | use libsyntax2::{ | 28 | use libsyntax2::{ |
29 | TextUnit, | 29 | TextUnit, TextRange, SyntaxRoot, |
30 | ast::{self, AstNode}, | 30 | ast::{self, AstNode, NameOwner}, |
31 | SyntaxKind::*, | ||
31 | }; | 32 | }; |
32 | use libeditor::{LineIndex, FileSymbol, find_node}; | 33 | use libeditor::{LineIndex, FileSymbol, find_node}; |
33 | 34 | ||
@@ -119,33 +120,58 @@ impl World { | |||
119 | Ok(index.clone()) | 120 | Ok(index.clone()) |
120 | } | 121 | } |
121 | 122 | ||
122 | pub fn world_symbols<'a>(&'a self, mut query: Query) -> impl Iterator<Item=(FileId, &'a FileSymbol)> + 'a { | 123 | pub fn world_symbols(&self, mut query: Query) -> Vec<(FileId, FileSymbol)> { |
123 | self.reindex(); | 124 | self.reindex(); |
124 | self.data.file_map.iter() | 125 | self.data.file_map.iter() |
125 | .flat_map(move |(id, data)| { | 126 | .flat_map(move |(id, data)| { |
126 | let symbols = data.symbols(); | 127 | let symbols = data.symbols(); |
127 | query.process(symbols).into_iter().map(move |s| (*id, s)) | 128 | query.process(symbols).into_iter().map(move |s| (*id, s)) |
128 | }) | 129 | }) |
130 | .collect() | ||
129 | } | 131 | } |
130 | 132 | ||
131 | pub fn approximately_resolve_symbol<'a>( | 133 | pub fn approximately_resolve_symbol( |
132 | &'a self, | 134 | &self, |
133 | id: FileId, | 135 | id: FileId, |
134 | offset: TextUnit, | 136 | offset: TextUnit, |
135 | ) -> Result<Vec<(FileId, &'a FileSymbol)>> { | 137 | ) -> Result<Vec<(FileId, FileSymbol)>> { |
136 | let file = self.file_syntax(id)?; | 138 | let file = self.file_syntax(id)?; |
137 | let syntax = file.syntax(); | 139 | let syntax = file.syntax_ref(); |
138 | let syntax = syntax.as_ref(); | 140 | if let Some(name_ref) = find_node::<ast::NameRef<_>>(syntax, offset) { |
139 | let name_ref = find_node::<ast::NameRef<_>>(syntax, offset); | 141 | return Ok(self.index_resolve(name_ref)); |
140 | let name = match name_ref { | 142 | } |
141 | None => return Ok(vec![]), | 143 | if let Some(name) = find_node::<ast::Name<_>>(syntax, offset) { |
142 | Some(name_ref) => name_ref.text(), | 144 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
143 | }; | 145 | if module.has_semi() { |
146 | return Ok(self.resolve_module(id, module)); | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | Ok(vec![]) | ||
151 | } | ||
144 | 152 | ||
153 | fn index_resolve(&self, name_ref: ast::NameRef<&SyntaxRoot>) -> Vec<(FileId, FileSymbol)> { | ||
154 | let name = name_ref.text(); | ||
145 | let mut query = Query::new(name.to_string()); | 155 | let mut query = Query::new(name.to_string()); |
146 | query.exact(); | 156 | query.exact(); |
147 | query.limit(4); | 157 | query.limit(4); |
148 | Ok(self.world_symbols(query).collect()) | 158 | self.world_symbols(query) |
159 | } | ||
160 | |||
161 | fn resolve_module(&self, id: FileId, module: ast::Module<&SyntaxRoot>) -> Vec<(FileId, FileSymbol)> { | ||
162 | let name = match module.name() { | ||
163 | Some(name) => name.text(), | ||
164 | None => return Vec::new(), | ||
165 | }; | ||
166 | let id = match self.resolve_relative_path(id, &PathBuf::from(format!("../{}.rs", name))) { | ||
167 | Some(id) => id, | ||
168 | None => return Vec::new(), | ||
169 | }; | ||
170 | vec![(id, FileSymbol { | ||
171 | name: name.clone(), | ||
172 | node_range: TextRange::offset_len(0.into(), 0.into()), | ||
173 | kind: MODULE, | ||
174 | })] | ||
149 | } | 175 | } |
150 | 176 | ||
151 | fn resolve_relative_path(&self, id: FileId, path: &Path) -> Option<FileId> { | 177 | fn resolve_relative_path(&self, id: FileId, path: &Path) -> Option<FileId> { |
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 { | |||
62 | self.limit = limit | 62 | self.limit = limit |
63 | } | 63 | } |
64 | 64 | ||
65 | pub(crate) fn process<'a>( | 65 | pub(crate) fn process( |
66 | &mut self, | 66 | &mut self, |
67 | file: &'a FileSymbols, | 67 | file: &FileSymbols, |
68 | ) -> Vec<&'a FileSymbol> { | 68 | ) -> Vec<FileSymbol> { |
69 | fn is_type(kind: SyntaxKind) -> bool { | 69 | fn is_type(kind: SyntaxKind) -> bool { |
70 | match kind { | 70 | match kind { |
71 | STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_DEF => true, | 71 | STRUCT_DEF | ENUM_DEF | TRAIT_DEF | TYPE_DEF => true, |
@@ -87,7 +87,7 @@ impl Query { | |||
87 | if self.exact && symbol.name != self.query { | 87 | if self.exact && symbol.name != self.query { |
88 | continue; | 88 | continue; |
89 | } | 89 | } |
90 | res.push(symbol); | 90 | res.push(symbol.clone()); |
91 | self.limit -= 1; | 91 | self.limit -= 1; |
92 | } | 92 | } |
93 | res | 93 | res |