diff options
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r-- | crates/ra_analysis/src/completion/complete_dot.rs | 10 | ||||
-rw-r--r-- | crates/ra_analysis/src/completion/complete_scope.rs | 14 | ||||
-rw-r--r-- | crates/ra_analysis/src/db.rs | 3 | ||||
-rw-r--r-- | crates/ra_analysis/src/goto_defenition.rs | 6 | ||||
-rw-r--r-- | crates/ra_analysis/src/hover.rs | 28 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 34 | ||||
-rw-r--r-- | crates/ra_analysis/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_analysis/src/runnables.rs | 9 | ||||
-rw-r--r-- | crates/ra_analysis/tests/test/main.rs | 3 |
9 files changed, 65 insertions, 44 deletions
diff --git a/crates/ra_analysis/src/completion/complete_dot.rs b/crates/ra_analysis/src/completion/complete_dot.rs index 031d8b98f..54ce1b638 100644 --- a/crates/ra_analysis/src/completion/complete_dot.rs +++ b/crates/ra_analysis/src/completion/complete_dot.rs | |||
@@ -1,4 +1,3 @@ | |||
1 | use ra_syntax::ast::AstNode; | ||
2 | use hir::{Ty, Def}; | 1 | use hir::{Ty, Def}; |
3 | 2 | ||
4 | use crate::Cancelable; | 3 | use crate::Cancelable; |
@@ -11,11 +10,12 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Ca | |||
11 | _ => return Ok(()), | 10 | _ => return Ok(()), |
12 | }; | 11 | }; |
13 | let infer_result = function.infer(ctx.db)?; | 12 | let infer_result = function.infer(ctx.db)?; |
14 | let receiver_ty = if let Some(ty) = infer_result.type_of_node(receiver.syntax()) { | 13 | let syntax_mapping = function.body_syntax_mapping(ctx.db)?; |
15 | ty | 14 | let expr = match syntax_mapping.node_expr(receiver) { |
16 | } else { | 15 | Some(expr) => expr, |
17 | return Ok(()); | 16 | None => return Ok(()), |
18 | }; | 17 | }; |
18 | let receiver_ty = infer_result[expr].clone(); | ||
19 | if !ctx.is_method_call { | 19 | if !ctx.is_method_call { |
20 | complete_fields(acc, ctx, receiver_ty)?; | 20 | complete_fields(acc, ctx, receiver_ty)?; |
21 | } | 21 | } |
diff --git a/crates/ra_analysis/src/completion/complete_scope.rs b/crates/ra_analysis/src/completion/complete_scope.rs index 4dead3689..ee9052d3d 100644 --- a/crates/ra_analysis/src/completion/complete_scope.rs +++ b/crates/ra_analysis/src/completion/complete_scope.rs | |||
@@ -15,19 +15,22 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) -> | |||
15 | None => return Ok(()), | 15 | None => return Ok(()), |
16 | }; | 16 | }; |
17 | if let Some(function) = &ctx.function { | 17 | if let Some(function) = &ctx.function { |
18 | let scopes = function.scopes(ctx.db); | 18 | let scopes = function.scopes(ctx.db)?; |
19 | complete_fn(acc, &scopes, ctx.offset); | 19 | complete_fn(acc, &scopes, ctx.offset); |
20 | } | 20 | } |
21 | 21 | ||
22 | let module_scope = module.scope(ctx.db)?; | 22 | let module_scope = module.scope(ctx.db)?; |
23 | let (file_id, _) = module.defenition_source(ctx.db)?; | ||
23 | module_scope | 24 | module_scope |
24 | .entries() | 25 | .entries() |
25 | .filter(|(_name, res)| { | 26 | .filter(|(_name, res)| { |
26 | // Don't expose this item | 27 | // Don't expose this item |
28 | // FIXME: this penetrates through all kinds of abstractions, | ||
29 | // we need to figura out the way to do it less ugly. | ||
27 | match res.import { | 30 | match res.import { |
28 | None => true, | 31 | None => true, |
29 | Some(import) => { | 32 | Some(import) => { |
30 | let range = import.range(ctx.db, module.file_id()); | 33 | let range = import.range(ctx.db, file_id); |
31 | !range.is_subrange(&ctx.leaf.range()) | 34 | !range.is_subrange(&ctx.leaf.range()) |
32 | } | 35 | } |
33 | } | 36 | } |
@@ -40,20 +43,17 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) -> | |||
40 | Ok(()) | 43 | Ok(()) |
41 | } | 44 | } |
42 | 45 | ||
43 | fn complete_fn(acc: &mut Completions, scopes: &hir::FnScopes, offset: TextUnit) { | 46 | fn complete_fn(acc: &mut Completions, scopes: &hir::ScopesWithSyntaxMapping, offset: TextUnit) { |
44 | let mut shadowed = FxHashSet::default(); | 47 | let mut shadowed = FxHashSet::default(); |
45 | scopes | 48 | scopes |
46 | .scope_chain_for_offset(offset) | 49 | .scope_chain_for_offset(offset) |
47 | .flat_map(|scope| scopes.entries(scope).iter()) | 50 | .flat_map(|scope| scopes.scopes.entries(scope).iter()) |
48 | .filter(|entry| shadowed.insert(entry.name())) | 51 | .filter(|entry| shadowed.insert(entry.name())) |
49 | .for_each(|entry| { | 52 | .for_each(|entry| { |
50 | CompletionItem::new(CompletionKind::Reference, entry.name().to_string()) | 53 | CompletionItem::new(CompletionKind::Reference, entry.name().to_string()) |
51 | .kind(CompletionItemKind::Binding) | 54 | .kind(CompletionItemKind::Binding) |
52 | .add_to(acc) | 55 | .add_to(acc) |
53 | }); | 56 | }); |
54 | if scopes.self_param.is_some() { | ||
55 | CompletionItem::new(CompletionKind::Reference, "self").add_to(acc); | ||
56 | } | ||
57 | } | 57 | } |
58 | 58 | ||
59 | #[cfg(test)] | 59 | #[cfg(test)] |
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 5422a400b..1709be5cf 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs | |||
@@ -106,6 +106,9 @@ salsa::database_storage! { | |||
106 | fn struct_data() for hir::db::StructDataQuery; | 106 | fn struct_data() for hir::db::StructDataQuery; |
107 | fn enum_data() for hir::db::EnumDataQuery; | 107 | fn enum_data() for hir::db::EnumDataQuery; |
108 | fn impls_in_module() for hir::db::ImplsInModuleQuery; | 108 | fn impls_in_module() for hir::db::ImplsInModuleQuery; |
109 | fn body_hir() for hir::db::BodyHirQuery; | ||
110 | fn body_syntax_mapping() for hir::db::BodySyntaxMappingQuery; | ||
111 | fn fn_signature() for hir::db::FnSignatureQuery; | ||
109 | } | 112 | } |
110 | } | 113 | } |
111 | } | 114 | } |
diff --git a/crates/ra_analysis/src/goto_defenition.rs b/crates/ra_analysis/src/goto_defenition.rs index e37421f8d..aa0616e3b 100644 --- a/crates/ra_analysis/src/goto_defenition.rs +++ b/crates/ra_analysis/src/goto_defenition.rs | |||
@@ -28,7 +28,7 @@ pub(crate) fn reference_defenition( | |||
28 | if let Some(fn_descr) = | 28 | if let Some(fn_descr) = |
29 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax())? | 29 | hir::source_binder::function_from_child_node(db, file_id, name_ref.syntax())? |
30 | { | 30 | { |
31 | let scope = fn_descr.scopes(db); | 31 | let scope = fn_descr.scopes(db)?; |
32 | // First try to resolve the symbol locally | 32 | // First try to resolve the symbol locally |
33 | if let Some(entry) = scope.resolve_local_name(name_ref) { | 33 | if let Some(entry) = scope.resolve_local_name(name_ref) { |
34 | let nav = NavigationTarget { | 34 | let nav = NavigationTarget { |
@@ -60,8 +60,8 @@ fn name_defenition( | |||
60 | if let Some(child_module) = | 60 | if let Some(child_module) = |
61 | hir::source_binder::module_from_declaration(db, file_id, module)? | 61 | hir::source_binder::module_from_declaration(db, file_id, module)? |
62 | { | 62 | { |
63 | let file_id = child_module.file_id(); | 63 | let (file_id, _) = child_module.defenition_source(db)?; |
64 | let name = match child_module.name() { | 64 | let name = match child_module.name(db)? { |
65 | Some(name) => name.to_string().into(), | 65 | Some(name) => name.to_string().into(), |
66 | None => "".into(), | 66 | None => "".into(), |
67 | }; | 67 | }; |
diff --git a/crates/ra_analysis/src/hover.rs b/crates/ra_analysis/src/hover.rs index 2cf79eebf..06632df4f 100644 --- a/crates/ra_analysis/src/hover.rs +++ b/crates/ra_analysis/src/hover.rs | |||
@@ -3,7 +3,7 @@ use ra_editor::find_node_at_offset; | |||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | AstNode, SyntaxNode, | 4 | AstNode, SyntaxNode, |
5 | ast::{self, NameOwner}, | 5 | ast::{self, NameOwner}, |
6 | algo::{find_covering_node, visit::{visitor, Visitor}}, | 6 | algo::{find_covering_node, find_leaf_at_offset, visit::{visitor, Visitor}}, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget}; | 9 | use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget}; |
@@ -26,13 +26,17 @@ pub(crate) fn hover( | |||
26 | } | 26 | } |
27 | } | 27 | } |
28 | if range.is_none() { | 28 | if range.is_none() { |
29 | let expr: ast::Expr = ctry!(find_node_at_offset(file.syntax(), position.offset)); | 29 | let node = find_leaf_at_offset(file.syntax(), position.offset).find_map(|leaf| { |
30 | leaf.ancestors() | ||
31 | .find(|n| ast::Expr::cast(*n).is_some() || ast::Pat::cast(*n).is_some()) | ||
32 | }); | ||
33 | let node = ctry!(node); | ||
30 | let frange = FileRange { | 34 | let frange = FileRange { |
31 | file_id: position.file_id, | 35 | file_id: position.file_id, |
32 | range: expr.syntax().range(), | 36 | range: node.range(), |
33 | }; | 37 | }; |
34 | res.extend(type_of(db, frange)?); | 38 | res.extend(type_of(db, frange)?); |
35 | range = Some(expr.syntax().range()); | 39 | range = Some(node.range()); |
36 | }; | 40 | }; |
37 | 41 | ||
38 | let range = ctry!(range); | 42 | let range = ctry!(range); |
@@ -60,7 +64,14 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Cancelable<Option | |||
60 | parent_fn | 64 | parent_fn |
61 | )?); | 65 | )?); |
62 | let infer = function.infer(db)?; | 66 | let infer = function.infer(db)?; |
63 | Ok(infer.type_of_node(node).map(|t| t.to_string())) | 67 | let syntax_mapping = function.body_syntax_mapping(db)?; |
68 | if let Some(expr) = ast::Expr::cast(node).and_then(|e| syntax_mapping.node_expr(e)) { | ||
69 | Ok(Some(infer[expr].to_string())) | ||
70 | } else if let Some(pat) = ast::Pat::cast(node).and_then(|p| syntax_mapping.node_pat(p)) { | ||
71 | Ok(Some(infer[pat].to_string())) | ||
72 | } else { | ||
73 | Ok(None) | ||
74 | } | ||
64 | } | 75 | } |
65 | 76 | ||
66 | // FIXME: this should not really use navigation target. Rather, approximatelly | 77 | // FIXME: this should not really use navigation target. Rather, approximatelly |
@@ -193,6 +204,13 @@ mod tests { | |||
193 | } | 204 | } |
194 | 205 | ||
195 | #[test] | 206 | #[test] |
207 | fn hover_for_local_variable_pat() { | ||
208 | let (analysis, position) = single_file_with_position("fn func(fo<|>o: i32) {}"); | ||
209 | let hover = analysis.hover(position).unwrap().unwrap(); | ||
210 | assert_eq!(hover.info, "i32"); | ||
211 | } | ||
212 | |||
213 | #[test] | ||
196 | fn test_type_of_for_function() { | 214 | fn test_type_of_for_function() { |
197 | let (analysis, range) = single_file_with_range( | 215 | let (analysis, range) = single_file_with_range( |
198 | " | 216 | " |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 6ab3c5476..07a966290 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -105,39 +105,35 @@ impl db::RootDatabase { | |||
105 | &self, | 105 | &self, |
106 | position: FilePosition, | 106 | position: FilePosition, |
107 | ) -> Cancelable<Vec<NavigationTarget>> { | 107 | ) -> Cancelable<Vec<NavigationTarget>> { |
108 | let descr = match source_binder::module_from_position(self, position)? { | 108 | let module = match source_binder::module_from_position(self, position)? { |
109 | None => return Ok(Vec::new()), | 109 | None => return Ok(Vec::new()), |
110 | Some(it) => it, | 110 | Some(it) => it, |
111 | }; | 111 | }; |
112 | let (file_id, decl) = match descr.parent_link_source(self) { | 112 | let (file_id, ast_module) = match module.declaration_source(self)? { |
113 | None => return Ok(Vec::new()), | 113 | None => return Ok(Vec::new()), |
114 | Some(it) => it, | 114 | Some(it) => it, |
115 | }; | 115 | }; |
116 | let decl = decl.borrowed(); | 116 | let ast_module = ast_module.borrowed(); |
117 | let decl_name = decl.name().unwrap(); | 117 | let name = ast_module.name().unwrap(); |
118 | Ok(vec![NavigationTarget { | 118 | Ok(vec![NavigationTarget { |
119 | file_id, | 119 | file_id, |
120 | name: decl_name.text(), | 120 | name: name.text(), |
121 | range: decl_name.syntax().range(), | 121 | range: name.syntax().range(), |
122 | kind: MODULE, | 122 | kind: MODULE, |
123 | ptr: None, | 123 | ptr: None, |
124 | }]) | 124 | }]) |
125 | } | 125 | } |
126 | /// Returns `Vec` for the same reason as `parent_module` | 126 | /// Returns `Vec` for the same reason as `parent_module` |
127 | pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { | 127 | pub(crate) fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { |
128 | let descr = match source_binder::module_from_file_id(self, file_id)? { | 128 | let module = match source_binder::module_from_file_id(self, file_id)? { |
129 | Some(it) => it, | ||
129 | None => return Ok(Vec::new()), | 130 | None => return Ok(Vec::new()), |
131 | }; | ||
132 | let krate = match module.krate(self)? { | ||
130 | Some(it) => it, | 133 | Some(it) => it, |
134 | None => return Ok(Vec::new()), | ||
131 | }; | 135 | }; |
132 | let root = descr.crate_root(); | 136 | Ok(vec![krate.crate_id()]) |
133 | let file_id = root.file_id(); | ||
134 | |||
135 | let crate_graph = self.crate_graph(); | ||
136 | let crate_id = crate_graph.crate_id_for_crate_root(file_id); | ||
137 | Ok(crate_id.into_iter().collect()) | ||
138 | } | ||
139 | pub(crate) fn crate_root(&self, crate_id: CrateId) -> FileId { | ||
140 | self.crate_graph().crate_root(crate_id) | ||
141 | } | 137 | } |
142 | pub(crate) fn find_all_refs( | 138 | pub(crate) fn find_all_refs( |
143 | &self, | 139 | &self, |
@@ -157,7 +153,7 @@ impl db::RootDatabase { | |||
157 | .collect::<Vec<_>>(); | 153 | .collect::<Vec<_>>(); |
158 | ret.extend( | 154 | ret.extend( |
159 | descr | 155 | descr |
160 | .scopes(self) | 156 | .scopes(self)? |
161 | .find_all_refs(binding) | 157 | .find_all_refs(binding) |
162 | .into_iter() | 158 | .into_iter() |
163 | .map(|ref_desc| (position.file_id, ref_desc.range)), | 159 | .map(|ref_desc| (position.file_id, ref_desc.range)), |
@@ -185,7 +181,7 @@ impl db::RootDatabase { | |||
185 | position.file_id, | 181 | position.file_id, |
186 | name_ref.syntax(), | 182 | name_ref.syntax(), |
187 | )?); | 183 | )?); |
188 | let scope = descr.scopes(db); | 184 | let scope = descr.scopes(db)?; |
189 | let resolved = ctry!(scope.resolve_local_name(name_ref)); | 185 | let resolved = ctry!(scope.resolve_local_name(name_ref)); |
190 | let resolved = resolved.ptr().resolve(source_file); | 186 | let resolved = resolved.ptr().resolve(source_file); |
191 | let binding = ctry!(find_node_at_offset::<ast::BindPat>( | 187 | let binding = ctry!(find_node_at_offset::<ast::BindPat>( |
@@ -209,7 +205,7 @@ impl db::RootDatabase { | |||
209 | }) | 205 | }) |
210 | .collect::<Vec<_>>(); | 206 | .collect::<Vec<_>>(); |
211 | if let Some(m) = source_binder::module_from_file_id(self, file_id)? { | 207 | if let Some(m) = source_binder::module_from_file_id(self, file_id)? { |
212 | for (name_node, problem) in m.problems(self) { | 208 | for (name_node, problem) in m.problems(self)? { |
213 | let source_root = self.file_source_root(file_id); | 209 | let source_root = self.file_source_root(file_id); |
214 | let diag = match problem { | 210 | let diag = match problem { |
215 | Problem::UnresolvedModule { candidate } => { | 211 | Problem::UnresolvedModule { candidate } => { |
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index feed44b2d..c8f846c56 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs | |||
@@ -401,7 +401,7 @@ impl Analysis { | |||
401 | } | 401 | } |
402 | /// Returns the root file of the given crate. | 402 | /// Returns the root file of the given crate. |
403 | pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> { | 403 | pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> { |
404 | Ok(self.db.crate_root(crate_id)) | 404 | Ok(self.db.crate_graph().crate_root(crate_id)) |
405 | } | 405 | } |
406 | /// Returns the set of possible targets to run for the current file. | 406 | /// Returns the set of possible targets to run for the current file. |
407 | pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { | 407 | pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { |
diff --git a/crates/ra_analysis/src/runnables.rs b/crates/ra_analysis/src/runnables.rs index 474267605..216209098 100644 --- a/crates/ra_analysis/src/runnables.rs +++ b/crates/ra_analysis/src/runnables.rs | |||
@@ -72,12 +72,15 @@ fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Opti | |||
72 | let range = module.syntax().range(); | 72 | let range = module.syntax().range(); |
73 | let module = | 73 | let module = |
74 | hir::source_binder::module_from_child_node(db, file_id, module.syntax()).ok()??; | 74 | hir::source_binder::module_from_child_node(db, file_id, module.syntax()).ok()??; |
75 | |||
76 | // FIXME: thread cancellation instead of `.ok`ing | ||
75 | let path = module | 77 | let path = module |
76 | .path_to_root() | 78 | .path_to_root(db) |
79 | .ok()? | ||
77 | .into_iter() | 80 | .into_iter() |
78 | .rev() | 81 | .rev() |
79 | .into_iter() | 82 | .filter_map(|it| it.name(db).ok()) |
80 | .filter_map(|it| it.name().map(Clone::clone)) | 83 | .filter_map(|it| it) |
81 | .join("::"); | 84 | .join("::"); |
82 | Some(Runnable { | 85 | Some(Runnable { |
83 | range, | 86 | range, |
diff --git a/crates/ra_analysis/tests/test/main.rs b/crates/ra_analysis/tests/test/main.rs index 26da7c10c..1f70af12a 100644 --- a/crates/ra_analysis/tests/test/main.rs +++ b/crates/ra_analysis/tests/test/main.rs | |||
@@ -31,6 +31,7 @@ fn test_unresolved_module_diagnostic() { | |||
31 | ); | 31 | ); |
32 | } | 32 | } |
33 | 33 | ||
34 | // FIXME: move this test to hir | ||
34 | #[test] | 35 | #[test] |
35 | fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { | 36 | fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { |
36 | let (analysis, file_id) = single_file("mod foo {}"); | 37 | let (analysis, file_id) = single_file("mod foo {}"); |
@@ -69,7 +70,7 @@ fn test_resolve_parent_module_for_inline() { | |||
69 | ); | 70 | ); |
70 | let symbols = analysis.parent_module(pos).unwrap(); | 71 | let symbols = analysis.parent_module(pos).unwrap(); |
71 | assert_eq_dbg( | 72 | assert_eq_dbg( |
72 | r#"[NavigationTarget { file_id: FileId(1), name: "bar", kind: MODULE, range: [18; 21), ptr: None }]"#, | 73 | r#"[NavigationTarget { file_id: FileId(1), name: "baz", kind: MODULE, range: [36; 39), ptr: None }]"#, |
73 | &symbols, | 74 | &symbols, |
74 | ); | 75 | ); |
75 | } | 76 | } |