diff options
Diffstat (limited to 'crates/ra_analysis/src')
-rw-r--r-- | crates/ra_analysis/src/completion.rs | 57 | ||||
-rw-r--r-- | crates/ra_analysis/src/db.rs | 13 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/function/imp.rs | 12 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/function/mod.rs | 29 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/function/scope.rs | 7 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/mod.rs | 39 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/imp.rs | 33 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 30 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/scope.rs | 5 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 77 | ||||
-rw-r--r-- | crates/ra_analysis/src/input.rs | 9 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 47 | ||||
-rw-r--r-- | crates/ra_analysis/src/mock_analysis.rs | 17 | ||||
-rw-r--r-- | crates/ra_analysis/src/symbol_index.rs | 5 | ||||
-rw-r--r-- | crates/ra_analysis/src/syntax_ptr.rs | 23 |
15 files changed, 205 insertions, 198 deletions
diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs index 286b6c376..6bd1233f9 100644 --- a/crates/ra_analysis/src/completion.rs +++ b/crates/ra_analysis/src/completion.rs | |||
@@ -1,22 +1,22 @@ | |||
1 | use rustc_hash::{FxHashMap, FxHashSet}; | 1 | use ra_editor::find_node_at_offset; |
2 | use ra_editor::{find_node_at_offset}; | ||
3 | use ra_syntax::{ | 2 | use ra_syntax::{ |
4 | AtomEdit, File, TextUnit, AstNode, SyntaxNodeRef, | ||
5 | algo::visit::{visitor, visitor_ctx, Visitor, VisitorCtx}, | 3 | algo::visit::{visitor, visitor_ctx, Visitor, VisitorCtx}, |
6 | ast::{self, AstChildren, LoopBodyOwner, ModuleItemOwner}, | 4 | ast::{self, AstChildren, LoopBodyOwner, ModuleItemOwner}, |
5 | AstNode, AtomEdit, File, | ||
7 | SyntaxKind::*, | 6 | SyntaxKind::*, |
7 | SyntaxNodeRef, TextUnit, | ||
8 | }; | 8 | }; |
9 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
11 | FileId, Cancelable, | ||
12 | input::FilesDatabase, | ||
13 | db::{self, SyntaxDatabase}, | 12 | db::{self, SyntaxDatabase}, |
14 | descriptors::DescriptorDatabase, | ||
15 | descriptors::function::FnScopes, | 13 | descriptors::function::FnScopes, |
16 | descriptors::module::{ModuleTree, ModuleId, ModuleScope}, | 14 | descriptors::module::{ModuleId, ModuleScope, ModuleTree}, |
15 | descriptors::DescriptorDatabase, | ||
16 | input::FilesDatabase, | ||
17 | Cancelable, FileId, | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | |||
20 | #[derive(Debug)] | 20 | #[derive(Debug)] |
21 | pub struct CompletionItem { | 21 | pub struct CompletionItem { |
22 | /// What user sees in pop-up | 22 | /// What user sees in pop-up |
@@ -27,7 +27,11 @@ pub struct CompletionItem { | |||
27 | pub snippet: Option<String>, | 27 | pub snippet: Option<String>, |
28 | } | 28 | } |
29 | 29 | ||
30 | pub(crate) fn resolve_based_completion(db: &db::RootDatabase, file_id: FileId, offset: TextUnit) -> Cancelable<Option<Vec<CompletionItem>>> { | 30 | pub(crate) fn resolve_based_completion( |
31 | db: &db::RootDatabase, | ||
32 | file_id: FileId, | ||
33 | offset: TextUnit, | ||
34 | ) -> Cancelable<Option<Vec<CompletionItem>>> { | ||
31 | let source_root_id = db.file_source_root(file_id); | 35 | let source_root_id = db.file_source_root(file_id); |
32 | let file = db.file_syntax(file_id); | 36 | let file = db.file_syntax(file_id); |
33 | let module_tree = db.module_tree(source_root_id)?; | 37 | let module_tree = db.module_tree(source_root_id)?; |
@@ -56,9 +60,12 @@ pub(crate) fn resolve_based_completion(db: &db::RootDatabase, file_id: FileId, o | |||
56 | Ok(Some(res)) | 60 | Ok(Some(res)) |
57 | } | 61 | } |
58 | 62 | ||
59 | 63 | pub(crate) fn find_target_module( | |
60 | 64 | module_tree: &ModuleTree, | |
61 | pub(crate) fn find_target_module(module_tree: &ModuleTree, module_id: ModuleId, file: &File, offset: TextUnit) -> Option<ModuleId> { | 65 | module_id: ModuleId, |
66 | file: &File, | ||
67 | offset: TextUnit, | ||
68 | ) -> Option<ModuleId> { | ||
62 | let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), offset)?; | 69 | let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), offset)?; |
63 | let mut crate_path = crate_path(name_ref)?; | 70 | let mut crate_path = crate_path(name_ref)?; |
64 | 71 | ||
@@ -71,8 +78,10 @@ pub(crate) fn find_target_module(module_tree: &ModuleTree, module_id: ModuleId, | |||
71 | } | 78 | } |
72 | 79 | ||
73 | fn crate_path(name_ref: ast::NameRef) -> Option<Vec<ast::NameRef>> { | 80 | fn crate_path(name_ref: ast::NameRef) -> Option<Vec<ast::NameRef>> { |
74 | let mut path = name_ref.syntax() | 81 | let mut path = name_ref |
75 | .parent().and_then(ast::PathSegment::cast)? | 82 | .syntax() |
83 | .parent() | ||
84 | .and_then(ast::PathSegment::cast)? | ||
76 | .parent_path(); | 85 | .parent_path(); |
77 | let mut res = Vec::new(); | 86 | let mut res = Vec::new(); |
78 | loop { | 87 | loop { |
@@ -80,8 +89,7 @@ fn crate_path(name_ref: ast::NameRef) -> Option<Vec<ast::NameRef>> { | |||
80 | match segment.kind()? { | 89 | match segment.kind()? { |
81 | ast::PathSegmentKind::Name(name) => res.push(name), | 90 | ast::PathSegmentKind::Name(name) => res.push(name), |
82 | ast::PathSegmentKind::CrateKw => break, | 91 | ast::PathSegmentKind::CrateKw => break, |
83 | ast::PathSegmentKind::SelfKw | ast::PathSegmentKind::SuperKw => | 92 | ast::PathSegmentKind::SelfKw | ast::PathSegmentKind::SuperKw => return None, |
84 | return None, | ||
85 | } | 93 | } |
86 | path = path.qualifier()?; | 94 | path = path.qualifier()?; |
87 | } | 95 | } |
@@ -89,7 +97,6 @@ fn crate_path(name_ref: ast::NameRef) -> Option<Vec<ast::NameRef>> { | |||
89 | Some(res) | 97 | Some(res) |
90 | } | 98 | } |
91 | 99 | ||
92 | |||
93 | pub(crate) fn scope_completion( | 100 | pub(crate) fn scope_completion( |
94 | db: &db::RootDatabase, | 101 | db: &db::RootDatabase, |
95 | file_id: FileId, | 102 | file_id: FileId, |
@@ -158,11 +165,7 @@ fn complete_module_items( | |||
158 | ); | 165 | ); |
159 | } | 166 | } |
160 | 167 | ||
161 | fn complete_name_ref( | 168 | fn complete_name_ref(file: &File, name_ref: ast::NameRef, acc: &mut Vec<CompletionItem>) { |
162 | file: &File, | ||
163 | name_ref: ast::NameRef, | ||
164 | acc: &mut Vec<CompletionItem>, | ||
165 | ) { | ||
166 | if !is_node::<ast::Path>(name_ref.syntax()) { | 169 | if !is_node::<ast::Path>(name_ref.syntax()) { |
167 | return; | 170 | return; |
168 | } | 171 | } |
@@ -273,7 +276,11 @@ fn is_in_loop_body(name_ref: ast::NameRef) -> bool { | |||
273 | .visit::<ast::LoopExpr, _>(LoopBodyOwner::loop_body) | 276 | .visit::<ast::LoopExpr, _>(LoopBodyOwner::loop_body) |
274 | .accept(node); | 277 | .accept(node); |
275 | if let Some(Some(body)) = loop_body { | 278 | if let Some(Some(body)) = loop_body { |
276 | if name_ref.syntax().range().is_subrange(&body.syntax().range()) { | 279 | if name_ref |
280 | .syntax() | ||
281 | .range() | ||
282 | .is_subrange(&body.syntax().range()) | ||
283 | { | ||
277 | return true; | 284 | return true; |
278 | } | 285 | } |
279 | } | 286 | } |
@@ -368,9 +375,9 @@ fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Vec<Completi | |||
368 | 375 | ||
369 | #[cfg(test)] | 376 | #[cfg(test)] |
370 | mod tests { | 377 | mod tests { |
371 | use test_utils::{assert_eq_dbg}; | 378 | use test_utils::assert_eq_dbg; |
372 | 379 | ||
373 | use crate::mock_analysis::{single_file_with_position}; | 380 | use crate::mock_analysis::single_file_with_position; |
374 | 381 | ||
375 | use super::*; | 382 | use super::*; |
376 | 383 | ||
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index f1ace3d5a..9ab273ad7 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -1,6 +1,4 @@ | |||
1 | use std::{ | 1 | use std::sync::Arc; |
2 | sync::Arc, | ||
3 | }; | ||
4 | 2 | ||
5 | use ra_editor::LineIndex; | 3 | use ra_editor::LineIndex; |
6 | use ra_syntax::File; | 4 | use ra_syntax::File; |
@@ -8,14 +6,13 @@ use salsa; | |||
8 | 6 | ||
9 | use crate::{ | 7 | use crate::{ |
10 | db, | 8 | db, |
11 | Cancelable, Canceled, | ||
12 | descriptors::{ | 9 | descriptors::{ |
13 | DescriptorDatabase, SubmodulesQuery, ModuleTreeQuery, ModuleScopeQuery, | 10 | DescriptorDatabase, FnScopesQuery, FnSyntaxQuery, ModuleScopeQuery, ModuleTreeQuery, |
14 | FnSyntaxQuery, FnScopesQuery | 11 | SubmodulesQuery, |
15 | }, | 12 | }, |
16 | symbol_index::SymbolIndex, | 13 | symbol_index::SymbolIndex, |
17 | syntax_ptr::{SyntaxPtrDatabase, ResolveSyntaxPtrQuery}, | 14 | syntax_ptr::{ResolveSyntaxPtrQuery, SyntaxPtrDatabase}, |
18 | FileId, | 15 | Cancelable, Canceled, FileId, |
19 | }; | 16 | }; |
20 | 17 | ||
21 | #[derive(Default, Debug)] | 18 | #[derive(Default, Debug)] |
diff --git a/crates/ra_analysis/src/descriptors/function/imp.rs b/crates/ra_analysis/src/descriptors/function/imp.rs index 0a006f733..11fffeefc 100644 --- a/crates/ra_analysis/src/descriptors/function/imp.rs +++ b/crates/ra_analysis/src/descriptors/function/imp.rs | |||
@@ -1,14 +1,10 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::ast::{AstNode, FnDef, FnDefNode}; |
4 | ast::{AstNode, FnDef, FnDefNode}, | ||
5 | }; | ||
6 | 4 | ||
7 | use crate::{ | 5 | use crate::descriptors::{ |
8 | descriptors::{ | 6 | function::{FnId, FnScopes}, |
9 | DescriptorDatabase, | 7 | DescriptorDatabase, |
10 | function::{FnId, FnScopes}, | ||
11 | }, | ||
12 | }; | 8 | }; |
13 | 9 | ||
14 | /// Resolve `FnId` to the corresponding `SyntaxNode` | 10 | /// Resolve `FnId` to the corresponding `SyntaxNode` |
diff --git a/crates/ra_analysis/src/descriptors/function/mod.rs b/crates/ra_analysis/src/descriptors/function/mod.rs index ae40f3e8f..d5db28a64 100644 --- a/crates/ra_analysis/src/descriptors/function/mod.rs +++ b/crates/ra_analysis/src/descriptors/function/mod.rs | |||
@@ -1,20 +1,16 @@ | |||
1 | pub(super) mod imp; | 1 | pub(super) mod imp; |
2 | mod scope; | 2 | mod scope; |
3 | 3 | ||
4 | use std::cmp::{min, max}; | 4 | use std::cmp::{max, min}; |
5 | 5 | ||
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | ast::{self, AstNode, DocCommentsOwner, NameOwner}, | 7 | ast::{self, AstNode, DocCommentsOwner, NameOwner}, |
8 | TextRange, TextUnit | 8 | TextRange, TextUnit, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{syntax_ptr::SyntaxPtr, FileId}; |
12 | FileId, | ||
13 | syntax_ptr::SyntaxPtr | ||
14 | }; | ||
15 | |||
16 | pub(crate) use self::scope::{FnScopes, resolve_local_name}; | ||
17 | 12 | ||
13 | pub(crate) use self::scope::{resolve_local_name, FnScopes}; | ||
18 | 14 | ||
19 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 15 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
20 | pub(crate) struct FnId(SyntaxPtr); | 16 | pub(crate) struct FnId(SyntaxPtr); |
@@ -26,14 +22,13 @@ impl FnId { | |||
26 | } | 22 | } |
27 | } | 23 | } |
28 | 24 | ||
29 | |||
30 | #[derive(Debug, Clone)] | 25 | #[derive(Debug, Clone)] |
31 | pub struct FnDescriptor { | 26 | pub struct FnDescriptor { |
32 | pub name: String, | 27 | pub name: String, |
33 | pub label: String, | 28 | pub label: String, |
34 | pub ret_type: Option<String>, | 29 | pub ret_type: Option<String>, |
35 | pub params: Vec<String>, | 30 | pub params: Vec<String>, |
36 | pub doc: Option<String> | 31 | pub doc: Option<String>, |
37 | } | 32 | } |
38 | 33 | ||
39 | impl FnDescriptor { | 34 | impl FnDescriptor { |
@@ -57,7 +52,9 @@ impl FnDescriptor { | |||
57 | }; | 52 | }; |
58 | 53 | ||
59 | if let Some((comment_range, docs)) = FnDescriptor::extract_doc_comments(node) { | 54 | if let Some((comment_range, docs)) = FnDescriptor::extract_doc_comments(node) { |
60 | let comment_range = comment_range.checked_sub(node.syntax().range().start()).unwrap(); | 55 | let comment_range = comment_range |
56 | .checked_sub(node.syntax().range().start()) | ||
57 | .unwrap(); | ||
61 | let start = comment_range.start().to_usize(); | 58 | let start = comment_range.start().to_usize(); |
62 | let end = comment_range.end().to_usize(); | 59 | let end = comment_range.end().to_usize(); |
63 | 60 | ||
@@ -94,7 +91,7 @@ impl FnDescriptor { | |||
94 | ret_type, | 91 | ret_type, |
95 | params, | 92 | params, |
96 | label: label.trim().to_owned(), | 93 | label: label.trim().to_owned(), |
97 | doc | 94 | doc, |
98 | }) | 95 | }) |
99 | } | 96 | } |
100 | 97 | ||
@@ -105,10 +102,13 @@ impl FnDescriptor { | |||
105 | 102 | ||
106 | let comment_text = node.doc_comment_text(); | 103 | let comment_text = node.doc_comment_text(); |
107 | 104 | ||
108 | let (begin, end) = node.doc_comments() | 105 | let (begin, end) = node |
106 | .doc_comments() | ||
109 | .map(|comment| comment.syntax().range()) | 107 | .map(|comment| comment.syntax().range()) |
110 | .map(|range| (range.start().to_usize(), range.end().to_usize())) | 108 | .map(|range| (range.start().to_usize(), range.end().to_usize())) |
111 | .fold((std::usize::MAX, std::usize::MIN), |acc, range| (min(acc.0, range.0), max(acc.1, range.1))); | 109 | .fold((std::usize::MAX, std::usize::MIN), |acc, range| { |
110 | (min(acc.0, range.0), max(acc.1, range.1)) | ||
111 | }); | ||
112 | 112 | ||
113 | let range = TextRange::from_to(TextUnit::from_usize(begin), TextUnit::from_usize(end)); | 113 | let range = TextRange::from_to(TextUnit::from_usize(begin), TextUnit::from_usize(end)); |
114 | 114 | ||
@@ -134,4 +134,3 @@ impl FnDescriptor { | |||
134 | res | 134 | res |
135 | } | 135 | } |
136 | } | 136 | } |
137 | |||
diff --git a/crates/ra_analysis/src/descriptors/function/scope.rs b/crates/ra_analysis/src/descriptors/function/scope.rs index d9929414c..62b46ffba 100644 --- a/crates/ra_analysis/src/descriptors/function/scope.rs +++ b/crates/ra_analysis/src/descriptors/function/scope.rs | |||
@@ -51,9 +51,7 @@ impl FnScopes { | |||
51 | &self.get(scope).entries | 51 | &self.get(scope).entries |
52 | } | 52 | } |
53 | pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a { | 53 | pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a { |
54 | generate(self.scope_for(node), move |&scope| { | 54 | generate(self.scope_for(node), move |&scope| self.get(scope).parent) |
55 | self.get(scope).parent | ||
56 | }) | ||
57 | } | 55 | } |
58 | fn root_scope(&mut self) -> ScopeId { | 56 | fn root_scope(&mut self) -> ScopeId { |
59 | let res = ScopeId(self.scopes.len() as u32); | 57 | let res = ScopeId(self.scopes.len() as u32); |
@@ -273,13 +271,12 @@ pub fn resolve_local_name<'a>( | |||
273 | 271 | ||
274 | #[cfg(test)] | 272 | #[cfg(test)] |
275 | mod tests { | 273 | mod tests { |
274 | use ra_editor::find_node_at_offset; | ||
276 | use ra_syntax::File; | 275 | use ra_syntax::File; |
277 | use test_utils::extract_offset; | 276 | use test_utils::extract_offset; |
278 | use ra_editor::{find_node_at_offset}; | ||
279 | 277 | ||
280 | use super::*; | 278 | use super::*; |
281 | 279 | ||
282 | |||
283 | fn do_check(code: &str, expected: &[&str]) { | 280 | fn do_check(code: &str, expected: &[&str]) { |
284 | let (off, code) = extract_offset(code); | 281 | let (off, code) = extract_offset(code); |
285 | let code = { | 282 | let code = { |
diff --git a/crates/ra_analysis/src/descriptors/mod.rs b/crates/ra_analysis/src/descriptors/mod.rs index e27f8314a..c28764336 100644 --- a/crates/ra_analysis/src/descriptors/mod.rs +++ b/crates/ra_analysis/src/descriptors/mod.rs | |||
@@ -1,24 +1,22 @@ | |||
1 | pub(crate) mod module; | ||
2 | pub(crate) mod function; | 1 | pub(crate) mod function; |
2 | pub(crate) mod module; | ||
3 | 3 | ||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | SmolStr, | ||
8 | ast::{self, AstNode, FnDefNode}, | 7 | ast::{self, AstNode, FnDefNode}, |
9 | TextRange | 8 | SmolStr, TextRange, |
10 | }; | 9 | }; |
11 | 10 | ||
12 | use crate::{ | 11 | use crate::{ |
13 | FileId, Cancelable, | ||
14 | db::SyntaxDatabase, | 12 | db::SyntaxDatabase, |
15 | descriptors::module::{ModuleTree, ModuleId, ModuleScope}, | 13 | descriptors::function::{resolve_local_name, FnId, FnScopes}, |
16 | descriptors::function::{FnId, FnScopes, resolve_local_name}, | 14 | descriptors::module::{ModuleId, ModuleScope, ModuleTree}, |
17 | input::SourceRootId, | 15 | input::SourceRootId, |
18 | syntax_ptr::{SyntaxPtrDatabase, LocalSyntaxPtr}, | 16 | syntax_ptr::{LocalSyntaxPtr, SyntaxPtrDatabase}, |
17 | Cancelable, FileId, | ||
19 | }; | 18 | }; |
20 | 19 | ||
21 | |||
22 | salsa::query_group! { | 20 | salsa::query_group! { |
23 | pub(crate) trait DescriptorDatabase: SyntaxDatabase + SyntaxPtrDatabase { | 21 | pub(crate) trait DescriptorDatabase: SyntaxDatabase + SyntaxPtrDatabase { |
24 | fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> { | 22 | fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> { |
@@ -49,23 +47,20 @@ salsa::query_group! { | |||
49 | #[derive(Debug)] | 47 | #[derive(Debug)] |
50 | pub struct ReferenceDescriptor { | 48 | pub struct ReferenceDescriptor { |
51 | pub range: TextRange, | 49 | pub range: TextRange, |
52 | pub name: String | 50 | pub name: String, |
53 | } | 51 | } |
54 | 52 | ||
55 | #[derive(Debug)] | 53 | #[derive(Debug)] |
56 | pub struct DeclarationDescriptor<'a> { | 54 | pub struct DeclarationDescriptor<'a> { |
57 | pat: ast::BindPat<'a>, | 55 | pat: ast::BindPat<'a>, |
58 | pub range: TextRange | 56 | pub range: TextRange, |
59 | } | 57 | } |
60 | 58 | ||
61 | impl<'a> DeclarationDescriptor<'a> { | 59 | impl<'a> DeclarationDescriptor<'a> { |
62 | pub fn new(pat: ast::BindPat) -> DeclarationDescriptor { | 60 | pub fn new(pat: ast::BindPat) -> DeclarationDescriptor { |
63 | let range = pat.syntax().range(); | 61 | let range = pat.syntax().range(); |
64 | 62 | ||
65 | DeclarationDescriptor { | 63 | DeclarationDescriptor { pat, range } |
66 | pat, | ||
67 | range | ||
68 | } | ||
69 | } | 64 | } |
70 | 65 | ||
71 | pub fn find_all_refs(&self) -> Vec<ReferenceDescriptor> { | 66 | pub fn find_all_refs(&self) -> Vec<ReferenceDescriptor> { |
@@ -73,22 +68,22 @@ impl<'a> DeclarationDescriptor<'a> { | |||
73 | 68 | ||
74 | let fn_def = match self.pat.syntax().ancestors().find_map(ast::FnDef::cast) { | 69 | let fn_def = match self.pat.syntax().ancestors().find_map(ast::FnDef::cast) { |
75 | Some(def) => def, | 70 | Some(def) => def, |
76 | None => return Default::default() | 71 | None => return Default::default(), |
77 | }; | 72 | }; |
78 | 73 | ||
79 | let fn_scopes = FnScopes::new(fn_def); | 74 | let fn_scopes = FnScopes::new(fn_def); |
80 | 75 | ||
81 | let refs : Vec<_> = fn_def.syntax().descendants() | 76 | let refs: Vec<_> = fn_def |
77 | .syntax() | ||
78 | .descendants() | ||
82 | .filter_map(ast::NameRef::cast) | 79 | .filter_map(ast::NameRef::cast) |
83 | .filter(|name_ref| { | 80 | .filter(|name_ref| match resolve_local_name(*name_ref, &fn_scopes) { |
84 | match resolve_local_name(*name_ref, &fn_scopes) { | 81 | None => false, |
85 | None => false, | 82 | Some(entry) => entry.ptr() == name_ptr, |
86 | Some(entry) => entry.ptr() == name_ptr, | ||
87 | } | ||
88 | }) | 83 | }) |
89 | .map(|name_ref| ReferenceDescriptor { | 84 | .map(|name_ref| ReferenceDescriptor { |
90 | name: name_ref.syntax().text().to_string(), | 85 | name: name_ref.syntax().text().to_string(), |
91 | range : name_ref.syntax().range(), | 86 | range: name_ref.syntax().range(), |
92 | }) | 87 | }) |
93 | .collect(); | 88 | .collect(); |
94 | 89 | ||
diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index dae3a356d..1c102f4e5 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs | |||
@@ -1,24 +1,25 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use relative_path::RelativePathBuf; | ||
4 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
5 | use ra_syntax::{ | 3 | use ra_syntax::{ |
6 | SmolStr, | ||
7 | ast::{self, NameOwner}, | 4 | ast::{self, NameOwner}, |
5 | SmolStr, | ||
8 | }; | 6 | }; |
7 | use relative_path::RelativePathBuf; | ||
8 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | FileId, Cancelable, FileResolverImp, db, | 11 | db, |
12 | input::{SourceRoot, SourceRootId}, | ||
13 | descriptors::DescriptorDatabase, | 12 | descriptors::DescriptorDatabase, |
13 | input::{SourceRoot, SourceRootId}, | ||
14 | Cancelable, FileId, FileResolverImp, | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | use super::{ | 17 | use super::{LinkData, LinkId, ModuleData, ModuleId, ModuleScope, ModuleTree, Problem}; |
17 | ModuleData, ModuleTree, ModuleId, LinkId, LinkData, Problem, ModuleScope | ||
18 | }; | ||
19 | |||
20 | 18 | ||
21 | pub(crate) fn submodules(db: &impl DescriptorDatabase, file_id: FileId) -> Cancelable<Arc<Vec<SmolStr>>> { | 19 | pub(crate) fn submodules( |
20 | db: &impl DescriptorDatabase, | ||
21 | file_id: FileId, | ||
22 | ) -> Cancelable<Arc<Vec<SmolStr>>> { | ||
22 | db::check_canceled(db)?; | 23 | db::check_canceled(db)?; |
23 | let file = db.file_syntax(file_id); | 24 | let file = db.file_syntax(file_id); |
24 | let root = file.ast(); | 25 | let root = file.ast(); |
@@ -57,13 +58,11 @@ pub(crate) fn module_tree( | |||
57 | Ok(Arc::new(res)) | 58 | Ok(Arc::new(res)) |
58 | } | 59 | } |
59 | 60 | ||
60 | |||
61 | #[derive(Clone, Hash, PartialEq, Eq, Debug)] | 61 | #[derive(Clone, Hash, PartialEq, Eq, Debug)] |
62 | pub struct Submodule { | 62 | pub struct Submodule { |
63 | pub name: SmolStr, | 63 | pub name: SmolStr, |
64 | } | 64 | } |
65 | 65 | ||
66 | |||
67 | fn create_module_tree<'a>( | 66 | fn create_module_tree<'a>( |
68 | db: &impl DescriptorDatabase, | 67 | db: &impl DescriptorDatabase, |
69 | source_root: SourceRootId, | 68 | source_root: SourceRootId, |
@@ -82,7 +81,15 @@ fn create_module_tree<'a>( | |||
82 | continue; // TODO: use explicit crate_roots here | 81 | continue; // TODO: use explicit crate_roots here |
83 | } | 82 | } |
84 | assert!(!roots.contains_key(&file_id)); | 83 | assert!(!roots.contains_key(&file_id)); |
85 | let module_id = build_subtree(db, &source_root, &mut tree, &mut visited, &mut roots, None, file_id)?; | 84 | let module_id = build_subtree( |
85 | db, | ||
86 | &source_root, | ||
87 | &mut tree, | ||
88 | &mut visited, | ||
89 | &mut roots, | ||
90 | None, | ||
91 | file_id, | ||
92 | )?; | ||
86 | roots.insert(file_id, module_id); | 93 | roots.insert(file_id, module_id); |
87 | } | 94 | } |
88 | Ok(tree) | 95 | Ok(tree) |
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 667553f74..302e3e81c 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs | |||
@@ -1,8 +1,11 @@ | |||
1 | pub(super) mod imp; | 1 | pub(super) mod imp; |
2 | pub(crate) mod scope; | 2 | pub(crate) mod scope; |
3 | 3 | ||
4 | use ra_syntax::{ | ||
5 | ast::{self, AstNode, NameOwner}, | ||
6 | SmolStr, SyntaxNode, | ||
7 | }; | ||
4 | use relative_path::RelativePathBuf; | 8 | use relative_path::RelativePathBuf; |
5 | use ra_syntax::{ast::{self, NameOwner, AstNode}, SmolStr, SyntaxNode}; | ||
6 | 9 | ||
7 | use crate::FileId; | 10 | use crate::FileId; |
8 | 11 | ||
@@ -16,9 +19,11 @@ pub(crate) struct ModuleTree { | |||
16 | 19 | ||
17 | impl ModuleTree { | 20 | impl ModuleTree { |
18 | pub(crate) fn modules_for_file(&self, file_id: FileId) -> Vec<ModuleId> { | 21 | pub(crate) fn modules_for_file(&self, file_id: FileId) -> Vec<ModuleId> { |
19 | self.mods.iter() | 22 | self.mods |
23 | .iter() | ||
20 | .enumerate() | 24 | .enumerate() |
21 | .filter(|(_idx, it)| it.file_id == file_id).map(|(idx, _)| ModuleId(idx as u32)) | 25 | .filter(|(_idx, it)| it.file_id == file_id) |
26 | .map(|(idx, _)| ModuleId(idx as u32)) | ||
22 | .collect() | 27 | .collect() |
23 | } | 28 | } |
24 | 29 | ||
@@ -50,7 +55,7 @@ impl ModuleId { | |||
50 | } | 55 | } |
51 | pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { | 56 | pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { |
52 | tree.module(self).parent | 57 | tree.module(self).parent |
53 | } | 58 | } |
54 | pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> { | 59 | pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> { |
55 | let link = self.parent_link(tree)?; | 60 | let link = self.parent_link(tree)?; |
56 | Some(tree.link(link).owner) | 61 | Some(tree.link(link).owner) |
@@ -69,18 +74,15 @@ impl ModuleId { | |||
69 | curr | 74 | curr |
70 | } | 75 | } |
71 | pub(crate) fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> { | 76 | pub(crate) fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> { |
72 | let link = tree.module(self) | 77 | let link = tree |
78 | .module(self) | ||
73 | .children | 79 | .children |
74 | .iter() | 80 | .iter() |
75 | .map(|&it| tree.link(it)) | 81 | .map(|&it| tree.link(it)) |
76 | .find(|it| it.name == name)?; | 82 | .find(|it| it.name == name)?; |
77 | Some(*link.points_to.first()?) | 83 | Some(*link.points_to.first()?) |
78 | } | 84 | } |
79 | pub(crate) fn problems( | 85 | pub(crate) fn problems(self, tree: &ModuleTree, root: ast::Root) -> Vec<(SyntaxNode, Problem)> { |
80 | self, | ||
81 | tree: &ModuleTree, | ||
82 | root: ast::Root, | ||
83 | ) -> Vec<(SyntaxNode, Problem)> { | ||
84 | tree.module(self) | 86 | tree.module(self) |
85 | .children | 87 | .children |
86 | .iter() | 88 | .iter() |
@@ -98,11 +100,7 @@ impl LinkId { | |||
98 | pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId { | 100 | pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId { |
99 | tree.link(self).owner | 101 | tree.link(self).owner |
100 | } | 102 | } |
101 | pub(crate) fn bind_source<'a>( | 103 | pub(crate) fn bind_source<'a>(self, tree: &ModuleTree, root: ast::Root<'a>) -> ast::Module<'a> { |
102 | self, | ||
103 | tree: &ModuleTree, | ||
104 | root: ast::Root<'a>, | ||
105 | ) -> ast::Module<'a> { | ||
106 | imp::modules(root) | 104 | imp::modules(root) |
107 | .find(|(name, _)| name == &tree.link(self).name) | 105 | .find(|(name, _)| name == &tree.link(self).name) |
108 | .unwrap() | 106 | .unwrap() |
@@ -125,7 +123,6 @@ struct LinkData { | |||
125 | problem: Option<Problem>, | 123 | problem: Option<Problem>, |
126 | } | 124 | } |
127 | 125 | ||
128 | |||
129 | impl ModuleTree { | 126 | impl ModuleTree { |
130 | fn module(&self, id: ModuleId) -> &ModuleData { | 127 | fn module(&self, id: ModuleId) -> &ModuleData { |
131 | &self.mods[id.0 as usize] | 128 | &self.mods[id.0 as usize] |
@@ -152,4 +149,3 @@ impl ModuleTree { | |||
152 | id | 149 | id |
153 | } | 150 | } |
154 | } | 151 | } |
155 | |||
diff --git a/crates/ra_analysis/src/descriptors/module/scope.rs b/crates/ra_analysis/src/descriptors/module/scope.rs index 846b8b44f..681e272c2 100644 --- a/crates/ra_analysis/src/descriptors/module/scope.rs +++ b/crates/ra_analysis/src/descriptors/module/scope.rs | |||
@@ -1,9 +1,8 @@ | |||
1 | //! Backend for module-level scope resolution & completion | 1 | //! Backend for module-level scope resolution & completion |
2 | 2 | ||
3 | |||
4 | use ra_syntax::{ | 3 | use ra_syntax::{ |
5 | ast::{self, ModuleItemOwner}, | 4 | ast::{self, ModuleItemOwner}, |
6 | File, AstNode, SmolStr, | 5 | AstNode, File, SmolStr, |
7 | }; | 6 | }; |
8 | 7 | ||
9 | use crate::syntax_ptr::LocalSyntaxPtr; | 8 | use crate::syntax_ptr::LocalSyntaxPtr; |
@@ -103,7 +102,7 @@ fn collect_imports(tree: ast::UseTree, acc: &mut Vec<Entry>) { | |||
103 | #[cfg(test)] | 102 | #[cfg(test)] |
104 | mod tests { | 103 | mod tests { |
105 | use super::*; | 104 | use super::*; |
106 | use ra_syntax::{File}; | 105 | use ra_syntax::File; |
107 | 106 | ||
108 | fn do_check(code: &str, expected: &[&str]) { | 107 | fn do_check(code: &str, expected: &[&str]) { |
109 | let file = File::parse(&code); | 108 | let file = File::parse(&code); |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 1eb8cb912..44077b507 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -13,24 +13,21 @@ use ra_syntax::{ | |||
13 | use rayon::prelude::*; | 13 | use rayon::prelude::*; |
14 | use relative_path::RelativePath; | 14 | use relative_path::RelativePath; |
15 | use rustc_hash::FxHashSet; | 15 | use rustc_hash::FxHashSet; |
16 | use salsa::{ParallelDatabase, Database}; | 16 | use salsa::{Database, ParallelDatabase}; |
17 | 17 | ||
18 | use crate::{ | 18 | use crate::{ |
19 | AnalysisChange, | 19 | completion::{resolve_based_completion, scope_completion, CompletionItem}, |
20 | db::{ | 20 | db::{self, FileSyntaxQuery, SyntaxDatabase}, |
21 | self, SyntaxDatabase, FileSyntaxQuery, | ||
22 | }, | ||
23 | input::{SourceRootId, FilesDatabase, SourceRoot, WORKSPACE}, | ||
24 | descriptors::{ | 21 | descriptors::{ |
25 | DescriptorDatabase, DeclarationDescriptor, | ||
26 | module::{ModuleTree, Problem}, | ||
27 | function::{FnDescriptor, FnId}, | 22 | function::{FnDescriptor, FnId}, |
23 | module::{ModuleTree, Problem}, | ||
24 | DeclarationDescriptor, DescriptorDatabase, | ||
28 | }, | 25 | }, |
29 | completion::{scope_completion, resolve_based_completion, CompletionItem}, | 26 | input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, |
30 | symbol_index::SymbolIndex, | 27 | symbol_index::SymbolIndex, |
31 | syntax_ptr::SyntaxPtrDatabase, | 28 | syntax_ptr::SyntaxPtrDatabase, |
32 | CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position, | 29 | AnalysisChange, Cancelable, CrateGraph, CrateId, Diagnostic, FileId, FileResolver, |
33 | Query, SourceChange, SourceFileEdit, Cancelable, | 30 | FileSystemEdit, Position, Query, SourceChange, SourceFileEdit, |
34 | }; | 31 | }; |
35 | 32 | ||
36 | #[derive(Clone, Debug)] | 33 | #[derive(Clone, Debug)] |
@@ -94,7 +91,6 @@ pub(crate) struct AnalysisHostImpl { | |||
94 | db: db::RootDatabase, | 91 | db: db::RootDatabase, |
95 | } | 92 | } |
96 | 93 | ||
97 | |||
98 | impl AnalysisHostImpl { | 94 | impl AnalysisHostImpl { |
99 | pub fn new() -> AnalysisHostImpl { | 95 | pub fn new() -> AnalysisHostImpl { |
100 | let db = db::RootDatabase::default(); | 96 | let db = db::RootDatabase::default(); |
@@ -108,7 +104,7 @@ impl AnalysisHostImpl { | |||
108 | } | 104 | } |
109 | pub fn analysis(&self) -> AnalysisImpl { | 105 | pub fn analysis(&self) -> AnalysisImpl { |
110 | AnalysisImpl { | 106 | AnalysisImpl { |
111 | db: self.db.fork() // freeze revision here | 107 | db: self.db.fork(), // freeze revision here |
112 | } | 108 | } |
113 | } | 109 | } |
114 | pub fn apply_change(&mut self, change: AnalysisChange) { | 110 | pub fn apply_change(&mut self, change: AnalysisChange) { |
@@ -120,7 +116,8 @@ impl AnalysisHostImpl { | |||
120 | .set(file_id, Arc::new(text)) | 116 | .set(file_id, Arc::new(text)) |
121 | } | 117 | } |
122 | if !(change.files_added.is_empty() && change.files_removed.is_empty()) { | 118 | if !(change.files_added.is_empty() && change.files_removed.is_empty()) { |
123 | let file_resolver = change.file_resolver | 119 | let file_resolver = change |
120 | .file_resolver | ||
124 | .expect("change resolver when changing set of files"); | 121 | .expect("change resolver when changing set of files"); |
125 | let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); | 122 | let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); |
126 | for (file_id, text) in change.files_added { | 123 | for (file_id, text) in change.files_added { |
@@ -174,7 +171,8 @@ impl AnalysisHostImpl { | |||
174 | .set((), Arc::new(libraries)); | 171 | .set((), Arc::new(libraries)); |
175 | } | 172 | } |
176 | if let Some(crate_graph) = change.crate_graph { | 173 | if let Some(crate_graph) = change.crate_graph { |
177 | self.db.query(crate::input::CrateGraphQuery) | 174 | self.db |
175 | .query(crate::input::CrateGraphQuery) | ||
178 | .set((), Arc::new(crate_graph)) | 176 | .set((), Arc::new(crate_graph)) |
179 | } | 177 | } |
180 | } | 178 | } |
@@ -194,18 +192,22 @@ impl AnalysisImpl { | |||
194 | } | 192 | } |
195 | pub fn world_symbols(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 193 | pub fn world_symbols(&self, query: Query) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
196 | let buf: Vec<Arc<SymbolIndex>> = if query.libs { | 194 | let buf: Vec<Arc<SymbolIndex>> = if query.libs { |
197 | self.db.libraries().iter() | 195 | self.db |
196 | .libraries() | ||
197 | .iter() | ||
198 | .map(|&lib_id| self.db.library_symbols(lib_id)) | 198 | .map(|&lib_id| self.db.library_symbols(lib_id)) |
199 | .collect() | 199 | .collect() |
200 | } else { | 200 | } else { |
201 | let files = &self.db.source_root(WORKSPACE).files; | 201 | let files = &self.db.source_root(WORKSPACE).files; |
202 | let db = self.db.clone(); | 202 | let db = self.db.clone(); |
203 | files.par_iter() | 203 | files |
204 | .par_iter() | ||
204 | .map_with(db, |db, &file_id| db.file_symbols(file_id)) | 205 | .map_with(db, |db, &file_id| db.file_symbols(file_id)) |
205 | .filter_map(|it| it.ok()) | 206 | .filter_map(|it| it.ok()) |
206 | .collect() | 207 | .collect() |
207 | }; | 208 | }; |
208 | self.db.query(FileSyntaxQuery) | 209 | self.db |
210 | .query(FileSyntaxQuery) | ||
209 | .sweep(salsa::SweepStrategy::default().discard_values()); | 211 | .sweep(salsa::SweepStrategy::default().discard_values()); |
210 | Ok(query.search(&buf)) | 212 | Ok(query.search(&buf)) |
211 | } | 213 | } |
@@ -216,7 +218,8 @@ impl AnalysisImpl { | |||
216 | pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 218 | pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
217 | let module_tree = self.module_tree(file_id)?; | 219 | let module_tree = self.module_tree(file_id)?; |
218 | 220 | ||
219 | let res = module_tree.modules_for_file(file_id) | 221 | let res = module_tree |
222 | .modules_for_file(file_id) | ||
220 | .into_iter() | 223 | .into_iter() |
221 | .filter_map(|module_id| { | 224 | .filter_map(|module_id| { |
222 | let link = module_id.parent_link(&module_tree)?; | 225 | let link = module_id.parent_link(&module_tree)?; |
@@ -237,7 +240,8 @@ impl AnalysisImpl { | |||
237 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { | 240 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { |
238 | let module_tree = self.module_tree(file_id)?; | 241 | let module_tree = self.module_tree(file_id)?; |
239 | let crate_graph = self.db.crate_graph(); | 242 | let crate_graph = self.db.crate_graph(); |
240 | let res = module_tree.modules_for_file(file_id) | 243 | let res = module_tree |
244 | .modules_for_file(file_id) | ||
241 | .into_iter() | 245 | .into_iter() |
242 | .map(|it| it.root(&module_tree)) | 246 | .map(|it| it.root(&module_tree)) |
243 | .map(|it| it.file_id(&module_tree)) | 247 | .map(|it| it.file_id(&module_tree)) |
@@ -249,7 +253,11 @@ impl AnalysisImpl { | |||
249 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | 253 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { |
250 | self.db.crate_graph().crate_roots[&crate_id] | 254 | self.db.crate_graph().crate_roots[&crate_id] |
251 | } | 255 | } |
252 | pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Cancelable<Option<Vec<CompletionItem>>> { | 256 | pub fn completions( |
257 | &self, | ||
258 | file_id: FileId, | ||
259 | offset: TextUnit, | ||
260 | ) -> Cancelable<Option<Vec<CompletionItem>>> { | ||
253 | let mut res = Vec::new(); | 261 | let mut res = Vec::new(); |
254 | let mut has_completions = false; | 262 | let mut has_completions = false; |
255 | if let Some(scope_based) = scope_completion(&self.db, file_id, offset) { | 263 | if let Some(scope_based) = scope_completion(&self.db, file_id, offset) { |
@@ -260,11 +268,7 @@ impl AnalysisImpl { | |||
260 | res.extend(scope_based); | 268 | res.extend(scope_based); |
261 | has_completions = true; | 269 | has_completions = true; |
262 | } | 270 | } |
263 | let res = if has_completions { | 271 | let res = if has_completions { Some(res) } else { None }; |
264 | Some(res) | ||
265 | } else { | ||
266 | None | ||
267 | }; | ||
268 | Ok(res) | 272 | Ok(res) |
269 | } | 273 | } |
270 | pub fn approximately_resolve_symbol( | 274 | pub fn approximately_resolve_symbol( |
@@ -326,12 +330,11 @@ impl AnalysisImpl { | |||
326 | let syntax = file.syntax(); | 330 | let syntax = file.syntax(); |
327 | 331 | ||
328 | // Find the binding associated with the offset | 332 | // Find the binding associated with the offset |
329 | let maybe_binding = find_node_at_offset::<ast::BindPat>(syntax, offset) | 333 | let maybe_binding = find_node_at_offset::<ast::BindPat>(syntax, offset).or_else(|| { |
330 | .or_else(|| { | 334 | let name_ref = find_node_at_offset::<ast::NameRef>(syntax, offset)?; |
331 | let name_ref = find_node_at_offset::<ast::NameRef>(syntax, offset)?; | 335 | let resolved = resolve_local_name(&self.db, file_id, name_ref)?; |
332 | let resolved = resolve_local_name(&self.db, file_id, name_ref)?; | 336 | find_node_at_offset::<ast::BindPat>(syntax, resolved.1.end()) |
333 | find_node_at_offset::<ast::BindPat>(syntax, resolved.1.end()) | 337 | }); |
334 | }); | ||
335 | 338 | ||
336 | let binding = match maybe_binding { | 339 | let binding = match maybe_binding { |
337 | None => return Vec::new(), | 340 | None => return Vec::new(), |
@@ -341,8 +344,11 @@ impl AnalysisImpl { | |||
341 | let decl = DeclarationDescriptor::new(binding); | 344 | let decl = DeclarationDescriptor::new(binding); |
342 | 345 | ||
343 | let mut ret = vec![(file_id, decl.range)]; | 346 | let mut ret = vec![(file_id, decl.range)]; |
344 | ret.extend(decl.find_all_refs().into_iter() | 347 | ret.extend( |
345 | .map(|ref_desc| (file_id, ref_desc.range ))); | 348 | decl.find_all_refs() |
349 | .into_iter() | ||
350 | .map(|ref_desc| (file_id, ref_desc.range)), | ||
351 | ); | ||
346 | 352 | ||
347 | ret | 353 | ret |
348 | } | 354 | } |
@@ -526,7 +532,8 @@ impl AnalysisImpl { | |||
526 | Some(id) => id, | 532 | Some(id) => id, |
527 | None => return Vec::new(), | 533 | None => return Vec::new(), |
528 | }; | 534 | }; |
529 | module_id.child(module_tree, name.as_str()) | 535 | module_id |
536 | .child(module_tree, name.as_str()) | ||
530 | .map(|it| it.file_id(module_tree)) | 537 | .map(|it| it.file_id(module_tree)) |
531 | .into_iter() | 538 | .into_iter() |
532 | .collect() | 539 | .collect() |
diff --git a/crates/ra_analysis/src/input.rs b/crates/ra_analysis/src/input.rs index b89b45133..ba8a17fd5 100644 --- a/crates/ra_analysis/src/input.rs +++ b/crates/ra_analysis/src/input.rs | |||
@@ -1,12 +1,9 @@ | |||
1 | use std::{ | 1 | use std::{fmt, sync::Arc}; |
2 | sync::Arc, | ||
3 | fmt, | ||
4 | }; | ||
5 | 2 | ||
6 | use salsa; | ||
7 | use rustc_hash::FxHashSet; | ||
8 | use relative_path::RelativePath; | 3 | use relative_path::RelativePath; |
9 | use rustc_hash::FxHashMap; | 4 | use rustc_hash::FxHashMap; |
5 | use rustc_hash::FxHashSet; | ||
6 | use salsa; | ||
10 | 7 | ||
11 | use crate::{symbol_index::SymbolIndex, FileResolverImp}; | 8 | use crate::{symbol_index::SymbolIndex, FileResolverImp}; |
12 | 9 | ||
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index e75411ec9..32aa7a1fd 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -6,23 +6,20 @@ extern crate relative_path; | |||
6 | extern crate rustc_hash; | 6 | extern crate rustc_hash; |
7 | extern crate salsa; | 7 | extern crate salsa; |
8 | 8 | ||
9 | mod input; | 9 | mod completion; |
10 | mod db; | 10 | mod db; |
11 | mod descriptors; | 11 | mod descriptors; |
12 | mod imp; | 12 | mod imp; |
13 | mod input; | ||
14 | pub mod mock_analysis; | ||
13 | mod symbol_index; | 15 | mod symbol_index; |
14 | mod completion; | ||
15 | mod syntax_ptr; | 16 | mod syntax_ptr; |
16 | pub mod mock_analysis; | ||
17 | 17 | ||
18 | use std::{ | 18 | use std::{fmt, sync::Arc}; |
19 | fmt, | ||
20 | sync::Arc, | ||
21 | }; | ||
22 | 19 | ||
23 | use ra_syntax::{AtomEdit, File, TextRange, TextUnit}; | 20 | use ra_syntax::{AtomEdit, File, TextRange, TextUnit}; |
24 | use relative_path::RelativePathBuf; | ||
25 | use rayon::prelude::*; | 21 | use rayon::prelude::*; |
22 | use relative_path::RelativePathBuf; | ||
26 | 23 | ||
27 | use crate::{ | 24 | use crate::{ |
28 | imp::{AnalysisHostImpl, AnalysisImpl, FileResolverImp}, | 25 | imp::{AnalysisHostImpl, AnalysisImpl, FileResolverImp}, |
@@ -30,13 +27,12 @@ use crate::{ | |||
30 | }; | 27 | }; |
31 | 28 | ||
32 | pub use crate::{ | 29 | pub use crate::{ |
33 | descriptors::function::FnDescriptor, | ||
34 | completion::CompletionItem, | 30 | completion::CompletionItem, |
35 | input::{FileId, FileResolver, CrateGraph, CrateId}, | 31 | descriptors::function::FnDescriptor, |
32 | input::{CrateGraph, CrateId, FileId, FileResolver}, | ||
36 | }; | 33 | }; |
37 | pub use ra_editor::{ | 34 | pub use ra_editor::{ |
38 | FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, | 35 | FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, RunnableKind, StructureNode, |
39 | RunnableKind, StructureNode, | ||
40 | }; | 36 | }; |
41 | 37 | ||
42 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | 38 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
@@ -50,8 +46,7 @@ impl std::fmt::Display for Canceled { | |||
50 | } | 46 | } |
51 | } | 47 | } |
52 | 48 | ||
53 | impl std::error::Error for Canceled { | 49 | impl std::error::Error for Canceled {} |
54 | } | ||
55 | 50 | ||
56 | #[derive(Default)] | 51 | #[derive(Default)] |
57 | pub struct AnalysisChange { | 52 | pub struct AnalysisChange { |
@@ -76,7 +71,6 @@ impl fmt::Debug for AnalysisChange { | |||
76 | } | 71 | } |
77 | } | 72 | } |
78 | 73 | ||
79 | |||
80 | impl AnalysisChange { | 74 | impl AnalysisChange { |
81 | pub fn new() -> AnalysisChange { | 75 | pub fn new() -> AnalysisChange { |
82 | AnalysisChange::default() | 76 | AnalysisChange::default() |
@@ -251,12 +245,15 @@ impl Analysis { | |||
251 | pub fn approximately_resolve_symbol( | 245 | pub fn approximately_resolve_symbol( |
252 | &self, | 246 | &self, |
253 | file_id: FileId, | 247 | file_id: FileId, |
254 | offset: TextUnit | 248 | offset: TextUnit, |
255 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 249 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
256 | self.imp | 250 | self.imp.approximately_resolve_symbol(file_id, offset) |
257 | .approximately_resolve_symbol(file_id, offset) | ||
258 | } | 251 | } |
259 | pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit, ) -> Cancelable<Vec<(FileId, TextRange)>> { | 252 | pub fn find_all_refs( |
253 | &self, | ||
254 | file_id: FileId, | ||
255 | offset: TextUnit, | ||
256 | ) -> Cancelable<Vec<(FileId, TextRange)>> { | ||
260 | Ok(self.imp.find_all_refs(file_id, offset)) | 257 | Ok(self.imp.find_all_refs(file_id, offset)) |
261 | } | 258 | } |
262 | pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 259 | pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
@@ -276,7 +273,11 @@ impl Analysis { | |||
276 | let file = self.imp.file_syntax(file_id); | 273 | let file = self.imp.file_syntax(file_id); |
277 | Ok(ra_editor::highlight(&file)) | 274 | Ok(ra_editor::highlight(&file)) |
278 | } | 275 | } |
279 | pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Cancelable<Option<Vec<CompletionItem>>> { | 276 | pub fn completions( |
277 | &self, | ||
278 | file_id: FileId, | ||
279 | offset: TextUnit, | ||
280 | ) -> Cancelable<Option<Vec<CompletionItem>>> { | ||
280 | self.imp.completions(file_id, offset) | 281 | self.imp.completions(file_id, offset) |
281 | } | 282 | } |
282 | pub fn assists(&self, file_id: FileId, range: TextRange) -> Cancelable<Vec<SourceChange>> { | 283 | pub fn assists(&self, file_id: FileId, range: TextRange) -> Cancelable<Vec<SourceChange>> { |
@@ -307,7 +308,11 @@ impl LibraryData { | |||
307 | let file = File::parse(text); | 308 | let file = File::parse(text); |
308 | (*file_id, file) | 309 | (*file_id, file) |
309 | })); | 310 | })); |
310 | LibraryData { files, file_resolver: FileResolverImp::new(file_resolver), symbol_index } | 311 | LibraryData { |
312 | files, | ||
313 | file_resolver: FileResolverImp::new(file_resolver), | ||
314 | symbol_index, | ||
315 | } | ||
311 | } | 316 | } |
312 | } | 317 | } |
313 | 318 | ||
diff --git a/crates/ra_analysis/src/mock_analysis.rs b/crates/ra_analysis/src/mock_analysis.rs index f72911192..76100f548 100644 --- a/crates/ra_analysis/src/mock_analysis.rs +++ b/crates/ra_analysis/src/mock_analysis.rs | |||
@@ -1,13 +1,10 @@ | |||
1 | |||
2 | use std::sync::Arc; | 1 | use std::sync::Arc; |
3 | 2 | ||
4 | use relative_path::{RelativePath, RelativePathBuf}; | ||
5 | use ra_syntax::TextUnit; | 3 | use ra_syntax::TextUnit; |
4 | use relative_path::{RelativePath, RelativePathBuf}; | ||
6 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; | 5 | use test_utils::{extract_offset, parse_fixture, CURSOR_MARKER}; |
7 | 6 | ||
8 | use crate::{ | 7 | use crate::{Analysis, AnalysisChange, AnalysisHost, FileId, FileResolver}; |
9 | AnalysisChange, Analysis, AnalysisHost, FileId, FileResolver, | ||
10 | }; | ||
11 | 8 | ||
12 | #[derive(Debug)] | 9 | #[derive(Debug)] |
13 | pub struct FilePosition { | 10 | pub struct FilePosition { |
@@ -51,7 +48,10 @@ impl MockAnalysis { | |||
51 | let mut res = MockAnalysis::new(); | 48 | let mut res = MockAnalysis::new(); |
52 | for entry in parse_fixture(fixture) { | 49 | for entry in parse_fixture(fixture) { |
53 | if entry.text.contains(CURSOR_MARKER) { | 50 | if entry.text.contains(CURSOR_MARKER) { |
54 | assert!(position.is_none(), "only one marker (<|>) per fixture is allowed"); | 51 | assert!( |
52 | position.is_none(), | ||
53 | "only one marker (<|>) per fixture is allowed" | ||
54 | ); | ||
55 | position = Some(res.add_file_with_position(&entry.meta, &entry.text)); | 55 | position = Some(res.add_file_with_position(&entry.meta, &entry.text)); |
56 | } else { | 56 | } else { |
57 | res.add_file(&entry.meta, &entry.text); | 57 | res.add_file(&entry.meta, &entry.text); |
@@ -73,7 +73,10 @@ impl MockAnalysis { | |||
73 | FilePosition { file_id, offset } | 73 | FilePosition { file_id, offset } |
74 | } | 74 | } |
75 | pub fn id_of(&self, path: &str) -> FileId { | 75 | pub fn id_of(&self, path: &str) -> FileId { |
76 | let (idx, _) = self.files.iter().enumerate() | 76 | let (idx, _) = self |
77 | .files | ||
78 | .iter() | ||
79 | .enumerate() | ||
77 | .find(|(_, (p, _text))| path == p) | 80 | .find(|(_, (p, _text))| path == p) |
78 | .expect("no file in this mock"); | 81 | .expect("no file in this mock"); |
79 | FileId(idx as u32 + 1) | 82 | FileId(idx as u32 + 1) |
diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs index 5f302cbda..b57ad5d33 100644 --- a/crates/ra_analysis/src/symbol_index.rs +++ b/crates/ra_analysis/src/symbol_index.rs | |||
@@ -57,10 +57,7 @@ impl SymbolIndex { | |||
57 | } | 57 | } |
58 | 58 | ||
59 | impl Query { | 59 | impl Query { |
60 | pub(crate) fn search( | 60 | pub(crate) fn search(self, indices: &[Arc<SymbolIndex>]) -> Vec<(FileId, FileSymbol)> { |
61 | self, | ||
62 | indices: &[Arc<SymbolIndex>], | ||
63 | ) -> Vec<(FileId, FileSymbol)> { | ||
64 | let mut op = fst::map::OpBuilder::new(); | 61 | let mut op = fst::map::OpBuilder::new(); |
65 | for file_symbols in indices.iter() { | 62 | for file_symbols in indices.iter() { |
66 | let automaton = fst::automaton::Subsequence::new(&self.lowercased); | 63 | let automaton = fst::automaton::Subsequence::new(&self.lowercased); |
diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_analysis/src/syntax_ptr.rs index c3c904633..612f75cd9 100644 --- a/crates/ra_analysis/src/syntax_ptr.rs +++ b/crates/ra_analysis/src/syntax_ptr.rs | |||
@@ -1,12 +1,12 @@ | |||
1 | use std::marker::PhantomData; | 1 | use std::marker::PhantomData; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | File, TextRange, SyntaxKind, SyntaxNode, SyntaxNodeRef, | ||
5 | ast::{self, AstNode}, | 4 | ast::{self, AstNode}, |
5 | File, SyntaxKind, SyntaxNode, SyntaxNodeRef, TextRange, | ||
6 | }; | 6 | }; |
7 | 7 | ||
8 | use crate::FileId; | ||
9 | use crate::db::SyntaxDatabase; | 8 | use crate::db::SyntaxDatabase; |
9 | use crate::FileId; | ||
10 | 10 | ||
11 | salsa::query_group! { | 11 | salsa::query_group! { |
12 | pub(crate) trait SyntaxPtrDatabase: SyntaxDatabase { | 12 | pub(crate) trait SyntaxPtrDatabase: SyntaxDatabase { |
@@ -52,12 +52,10 @@ trait ToAst { | |||
52 | impl<'a> ToAst for &'a OwnedAst<ast::FnDef<'static>> { | 52 | impl<'a> ToAst for &'a OwnedAst<ast::FnDef<'static>> { |
53 | type Ast = ast::FnDef<'a>; | 53 | type Ast = ast::FnDef<'a>; |
54 | fn to_ast(self) -> ast::FnDef<'a> { | 54 | fn to_ast(self) -> ast::FnDef<'a> { |
55 | ast::FnDef::cast(self.syntax.borrowed()) | 55 | ast::FnDef::cast(self.syntax.borrowed()).unwrap() |
56 | .unwrap() | ||
57 | } | 56 | } |
58 | } | 57 | } |
59 | 58 | ||
60 | |||
61 | /// A pionter to a syntax node inside a file. | 59 | /// A pionter to a syntax node inside a file. |
62 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 60 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
63 | pub(crate) struct LocalSyntaxPtr { | 61 | pub(crate) struct LocalSyntaxPtr { |
@@ -79,22 +77,29 @@ impl LocalSyntaxPtr { | |||
79 | if curr.range() == self.range && curr.kind() == self.kind { | 77 | if curr.range() == self.range && curr.kind() == self.kind { |
80 | return curr.owned(); | 78 | return curr.owned(); |
81 | } | 79 | } |
82 | curr = curr.children() | 80 | curr = curr |
81 | .children() | ||
83 | .find(|it| self.range.is_subrange(&it.range())) | 82 | .find(|it| self.range.is_subrange(&it.range())) |
84 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) | 83 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) |
85 | } | 84 | } |
86 | } | 85 | } |
87 | 86 | ||
88 | pub(crate) fn into_global(self, file_id: FileId) -> SyntaxPtr { | 87 | pub(crate) fn into_global(self, file_id: FileId) -> SyntaxPtr { |
89 | SyntaxPtr { file_id, local: self} | 88 | SyntaxPtr { |
89 | file_id, | ||
90 | local: self, | ||
91 | } | ||
90 | } | 92 | } |
91 | } | 93 | } |
92 | 94 | ||
93 | |||
94 | #[test] | 95 | #[test] |
95 | fn test_local_syntax_ptr() { | 96 | fn test_local_syntax_ptr() { |
96 | let file = File::parse("struct Foo { f: u32, }"); | 97 | let file = File::parse("struct Foo { f: u32, }"); |
97 | let field = file.syntax().descendants().find_map(ast::NamedFieldDef::cast).unwrap(); | 98 | let field = file |
99 | .syntax() | ||
100 | .descendants() | ||
101 | .find_map(ast::NamedFieldDef::cast) | ||
102 | .unwrap(); | ||
98 | let ptr = LocalSyntaxPtr::new(field.syntax()); | 103 | let ptr = LocalSyntaxPtr::new(field.syntax()); |
99 | let field_syntax = ptr.resolve(&file); | 104 | let field_syntax = ptr.resolve(&file); |
100 | assert_eq!(field.syntax(), field_syntax); | 105 | assert_eq!(field.syntax(), field_syntax); |