aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r--crates/ra_analysis/src/imp.rs38
-rw-r--r--crates/ra_analysis/src/lib.rs5
-rw-r--r--crates/ra_analysis/tests/tests.rs12
3 files changed, 38 insertions, 17 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 975afc145..99bcf0666 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -144,7 +144,7 @@ impl AnalysisImpl {
144 } else { 144 } else {
145 let files = &self.db.source_root(WORKSPACE).files; 145 let files = &self.db.source_root(WORKSPACE).files;
146 146
147 /// Need to wrap Snapshot to provide `Clon` impl for `map_with` 147 /// Need to wrap Snapshot to provide `Clone` impl for `map_with`
148 struct Snap(salsa::Snapshot<db::RootDatabase>); 148 struct Snap(salsa::Snapshot<db::RootDatabase>);
149 impl Clone for Snap { 149 impl Clone for Snap {
150 fn clone(&self) -> Snap { 150 fn clone(&self) -> Snap {
@@ -164,7 +164,7 @@ impl AnalysisImpl {
164 .sweep(salsa::SweepStrategy::default().discard_values()); 164 .sweep(salsa::SweepStrategy::default().discard_values());
165 Ok(query.search(&buf)) 165 Ok(query.search(&buf))
166 } 166 }
167 /// This return `Vec`: a module may be included from several places. We 167 /// This returns `Vec` because a module may be included from several places. We
168 /// don't handle this case yet though, so the Vec has length at most one. 168 /// don't handle this case yet though, so the Vec has length at most one.
169 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { 169 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> {
170 let descr = match source_binder::module_from_position(&*self.db, position)? { 170 let descr = match source_binder::module_from_position(&*self.db, position)? {
@@ -206,7 +206,7 @@ impl AnalysisImpl {
206 pub fn approximately_resolve_symbol( 206 pub fn approximately_resolve_symbol(
207 &self, 207 &self,
208 position: FilePosition, 208 position: FilePosition,
209 ) -> Cancelable<Vec<(FileId, FileSymbol)>> { 209 ) -> Cancelable<Option<(TextRange, Vec<(FileId, FileSymbol)>)>> {
210 let file = self.db.source_file(position.file_id); 210 let file = self.db.source_file(position.file_id);
211 let syntax = file.syntax(); 211 let syntax = file.syntax();
212 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { 212 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) {
@@ -218,20 +218,22 @@ impl AnalysisImpl {
218 let scope = fn_descr.scope(&*self.db); 218 let scope = fn_descr.scope(&*self.db);
219 // First try to resolve the symbol locally 219 // First try to resolve the symbol locally
220 if let Some(entry) = scope.resolve_local_name(name_ref) { 220 if let Some(entry) = scope.resolve_local_name(name_ref) {
221 let mut vec = vec![]; 221 let vec = vec![(
222 vec.push((
223 position.file_id, 222 position.file_id,
224 FileSymbol { 223 FileSymbol {
225 name: entry.name().clone(), 224 name: entry.name().clone(),
226 node_range: entry.ptr().range(), 225 node_range: entry.ptr().range(),
227 kind: NAME, 226 kind: NAME,
228 }, 227 },
229 )); 228 )];
230 return Ok(vec); 229 return Ok(Some((name_ref.syntax().range(), vec)));
231 }; 230 };
232 } 231 }
233 // If that fails try the index based approach. 232 // If that fails try the index based approach.
234 return self.index_resolve(name_ref); 233 return Ok(Some((
234 name_ref.syntax().range(),
235 self.index_resolve(name_ref)?,
236 )));
235 } 237 }
236 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { 238 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) {
237 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { 239 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
@@ -248,7 +250,7 @@ impl AnalysisImpl {
248 node_range: TextRange::offset_len(0.into(), 0.into()), 250 node_range: TextRange::offset_len(0.into(), 0.into()),
249 kind: MODULE, 251 kind: MODULE,
250 }; 252 };
251 return Ok(vec![(file_id, symbol)]); 253 return Ok(Some((name.syntax().range(), vec![(file_id, symbol)])));
252 } 254 }
253 } 255 }
254 _ => (), 256 _ => (),
@@ -256,7 +258,10 @@ impl AnalysisImpl {
256 } 258 }
257 } 259 }
258 } 260 }
259 Ok(vec![]) 261 let range =
262 ctry!(ra_syntax::algo::find_leaf_at_offset(syntax, position.offset).left_biased())
263 .range();
264 Ok(Some((range, vec![])))
260 } 265 }
261 266
262 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { 267 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> {
@@ -318,6 +323,19 @@ impl AnalysisImpl {
318 323
319 Ok(symbol.docs(&file)) 324 Ok(symbol.docs(&file))
320 } 325 }
326 pub fn doc_text_for(&self, file_id: FileId, symbol: FileSymbol) -> Cancelable<Option<String>> {
327 let file = self.db.source_file(file_id);
328 let result = match (symbol.description(&file), symbol.docs(&file)) {
329 (Some(desc), Some(docs)) => {
330 Some("```rust\n".to_string() + &*desc + "\n```\n\n" + &*docs)
331 }
332 (Some(desc), None) => Some("```rust\n".to_string() + &*desc + "\n```"),
333 (None, Some(docs)) => Some(docs),
334 _ => None,
335 };
336
337 Ok(result)
338 }
321 339
322 pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { 340 pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> {
323 let syntax = self.db.source_file(file_id); 341 let syntax = self.db.source_file(file_id);
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 4b8b10816..d33f3e4ca 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -236,7 +236,7 @@ impl Analysis {
236 pub fn approximately_resolve_symbol( 236 pub fn approximately_resolve_symbol(
237 &self, 237 &self,
238 position: FilePosition, 238 position: FilePosition,
239 ) -> Cancelable<Vec<(FileId, FileSymbol)>> { 239 ) -> Cancelable<Option<(TextRange, Vec<(FileId, FileSymbol)>)>> {
240 self.imp.approximately_resolve_symbol(position) 240 self.imp.approximately_resolve_symbol(position)
241 } 241 }
242 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { 242 pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> {
@@ -249,6 +249,9 @@ impl Analysis {
249 ) -> Cancelable<Option<String>> { 249 ) -> Cancelable<Option<String>> {
250 self.imp.doc_comment_for(file_id, symbol) 250 self.imp.doc_comment_for(file_id, symbol)
251 } 251 }
252 pub fn doc_text_for(&self, file_id: FileId, symbol: FileSymbol) -> Cancelable<Option<String>> {
253 self.imp.doc_text_for(file_id, symbol)
254 }
252 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { 255 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> {
253 self.imp.parent_module(position) 256 self.imp.parent_module(position)
254 } 257 }
diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs
index 4ce2c5c85..05ad687ae 100644
--- a/crates/ra_analysis/tests/tests.rs
+++ b/crates/ra_analysis/tests/tests.rs
@@ -21,9 +21,9 @@ fn approximate_resolve_works_in_items() {
21 ", 21 ",
22 ); 22 );
23 23
24 let symbols = analysis.approximately_resolve_symbol(pos).unwrap(); 24 let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap();
25 assert_eq_dbg( 25 assert_eq_dbg(
26 r#"[(FileId(1), FileSymbol { name: "Foo", node_range: [0; 11), kind: STRUCT_DEF })]"#, 26 r#"([23; 26), [(FileId(1), FileSymbol { name: "Foo", node_range: [0; 11), kind: STRUCT_DEF })])"#,
27 &symbols, 27 &symbols,
28 ); 28 );
29} 29}
@@ -39,9 +39,9 @@ fn test_resolve_module() {
39 ", 39 ",
40 ); 40 );
41 41
42 let symbols = analysis.approximately_resolve_symbol(pos).unwrap(); 42 let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap();
43 assert_eq_dbg( 43 assert_eq_dbg(
44 r#"[(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })]"#, 44 r#"([4; 7), [(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })])"#,
45 &symbols, 45 &symbols,
46 ); 46 );
47 47
@@ -54,9 +54,9 @@ fn test_resolve_module() {
54 ", 54 ",
55 ); 55 );
56 56
57 let symbols = analysis.approximately_resolve_symbol(pos).unwrap(); 57 let symbols = analysis.approximately_resolve_symbol(pos).unwrap().unwrap();
58 assert_eq_dbg( 58 assert_eq_dbg(
59 r#"[(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })]"#, 59 r#"([4; 7), [(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })])"#,
60 &symbols, 60 &symbols,
61 ); 61 );
62} 62}